[Nearby Connections] Add OS_INFO for NC C++.

PiperOrigin-RevId: 509443158
This commit is contained in:
Edwin Wu
2023-02-14 00:05:17 -08:00
committed by Copybara-Service
parent 1e0e0a922b
commit 1e229e31c5
15 changed files with 162 additions and 45 deletions
+12 -4
View File
@@ -35,6 +35,7 @@
#include "connections/implementation/mediums/utils.h"
#include "connections/implementation/offline_frames.h"
#include "connections/medium_selector.h"
#include "connections/implementation/proto/offline_wire_formats.pb.h"
#include "internal/platform/base64_utils.h"
#include "internal/platform/bluetooth_utils.h"
#include "internal/platform/logging.h"
@@ -757,7 +758,8 @@ bool BasePcpHandler::CanReceiveIncomingConnection(ClientProxy* client) const {
Exception BasePcpHandler::WriteConnectionRequestFrame(
const ConnectionInfo& conection_info, EndpointChannel* endpoint_channel) {
return endpoint_channel->Write(parser::ForConnectionRequest(conection_info));
return endpoint_channel->Write(
parser::ForConnectionRequest(conection_info));
}
void BasePcpHandler::ProcessPreConnectionInitiationFailure(
@@ -843,7 +845,8 @@ Status BasePcpHandler::AcceptConnection(
}
Exception write_exception =
channel->Write(parser::ForConnectionResponse(Status::kSuccess));
channel->Write(parser::ForConnectionResponse(
Status::kSuccess, client->GetLocalOsInfo()));
if (!write_exception.Ok()) {
NEARBY_LOGS(INFO)
<< "AcceptConnection: failed to send response: endpoint_id="
@@ -899,8 +902,9 @@ Status BasePcpHandler::RejectConnection(ClientProxy* client,
return;
}
Exception write_exception = channel->Write(
parser::ForConnectionResponse(Status::kConnectionRejected));
Exception write_exception =
channel->Write(parser::ForConnectionResponse(
Status::kConnectionRejected, client->GetLocalOsInfo()));
if (!write_exception.Ok()) {
NEARBY_LOGS(INFO)
<< "RejectConnection: failed to send response: endpoint_id="
@@ -965,6 +969,10 @@ void BasePcpHandler::OnIncomingFrame(
client->RemoteEndpointRejectedConnection(endpoint_id);
}
if (connection_response.has_os_info()) {
client->SetRemoteOsInfo(endpoint_id, connection_response.os_info());
}
EvaluateConnectionResult(client, endpoint_id,
/* can_close_immediately= */ true);
@@ -31,7 +31,6 @@
#include "connections/listeners.h"
#include "connections/params.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/exception.h"
#include "internal/platform/medium_environment.h"
#include "internal/platform/pipe.h"
@@ -41,6 +40,7 @@ namespace nearby {
namespace connections {
namespace {
using ::location::nearby::connections::OsInfo;
using ::location::nearby::proto::connections::Medium;
using ::testing::_;
using ::testing::AtLeast;
@@ -649,8 +649,9 @@ TEST_P(BasePcpHandlerTest, OnIncomingFrameChangesState) {
EXPECT_EQ(pcp_handler.AcceptConnection(&client, endpoint_id, {}),
Status{Status::kSuccess});
NEARBY_LOG(INFO, "Simulating remote accept: id=%s", endpoint_id.c_str());
auto frame =
parser::FromBytes(parser::ForConnectionResponse(Status::kSuccess));
OsInfo os_info;
auto frame = parser::FromBytes(
parser::ForConnectionResponse(Status::kSuccess, os_info));
EXPECT_CALL(mock_connection_listener_.bandwidth_changed_cb, Call).Times(1);
pcp_handler.OnIncomingFrame(frame.result(), endpoint_id, &client,
connect_medium, packet_meta_data);
+51 -4
View File
@@ -18,6 +18,7 @@
#include <functional>
#include <limits>
#include <memory>
#include <optional>
#include <sstream>
#include <string>
#include <utility>
@@ -25,19 +26,22 @@
#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 "absl/strings/str_format.h"
#include "internal/analytics/event_logger.h"
#include "internal/platform/error_code_recorder.h"
#include "internal/platform/feature_flags.h"
#include "internal/platform/implementation/platform.h"
#include "internal/platform/logging.h"
#include "internal/platform/mutex_lock.h"
#include "internal/platform/os_name.h"
#include "internal/platform/prng.h"
#include "proto/connections_enums.pb.h"
namespace nearby {
namespace connections {
using ::location::nearby::connections::OsInfo;
// The definition is necessary before C++17.
constexpr absl::Duration
ClientProxy::kHighPowerAdvertisementEndpointIdCacheTimeout;
@@ -56,6 +60,8 @@ ClientProxy::ClientProxy(::nearby::analytics::EventLogger* event_logger)
[this](const ErrorCodeParams& params) {
analytics_recorder_->OnErrorCode(params);
});
local_os_info_.set_type(
OSNameToOsInfoType(api::ImplementationPlatform::GetCurrentOS()));
}
ClientProxy::~ClientProxy() { Reset(); }
@@ -627,6 +633,26 @@ void ClientProxy::CancelEndpoint(const std::string& endpoint_id) {
cancellation_flags_.erase(item);
}
const OsInfo& ClientProxy::GetLocalOsInfo() const {
return local_os_info_;
}
std::optional<OsInfo> ClientProxy::GetRemoteOsInfo(
absl::string_view endpoint_id) const {
const Connection* item = LookupConnection(endpoint_id);
if (item != nullptr) {
return item->os_info;
}
return std::nullopt;
}
void ClientProxy::SetRemoteOsInfo(absl::string_view endpoint_id,
const OsInfo& remote_os_info) {
Connection* item = LookupConnection(endpoint_id);
if (item != nullptr) {
item->os_info.emplace(remote_os_info);
}
}
void ClientProxy::CancelAllEndpoints() {
for (const auto& item : cancellation_flags_) {
CancellationFlag* cancellation_flag = item.second.get();
@@ -653,13 +679,13 @@ void ClientProxy::OnPayload(const std::string& endpoint_id, Payload payload) {
}
const ClientProxy::Connection* ClientProxy::LookupConnection(
const std::string& endpoint_id) const {
absl::string_view 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) {
absl::string_view endpoint_id) {
auto item = connections_.find(endpoint_id);
return item != connections_.end() ? &item->second : nullptr;
}
@@ -795,6 +821,21 @@ void ClientProxy::CancelClearLocalHighVisModeCacheEndpointIdAlarm() {
}
}
OsInfo::OsType ClientProxy::OSNameToOsInfoType(api::OSName osName) {
switch (osName) {
case api::OSName::kLinux:
return OsInfo::LINUX;
case api::OSName::kWindows:
return OsInfo::WINDOWS;
case api::OSName::kApple:
return OsInfo::APPLE;
case api::OSName::kChromeOS:
return OsInfo::CHROME_OS;
case api::OSName::kAndroid:
return OsInfo::ANDROID;
}
}
std::string ClientProxy::ToString(PayloadProgressInfo::Status status) const {
switch (status) {
case PayloadProgressInfo::Status::kSuccess:
@@ -825,7 +866,12 @@ std::string ClientProxy::Dump() {
sstream << " Connections: " << std::endl;
for (auto it = connections_.begin(); it != connections_.end(); ++it) {
// TODO(deling): write Connection.ToString()
sstream << " " << it->first << " : " << it->second.connection_token
sstream << " " << it->first << " :(connection token) "
<< it->second.connection_token << ", (remote os type) "
<< (it->second.os_info.has_value()
? location::nearby::connections::OsInfo::OsType_Name(
it->second.os_info->type())
: "unknown")
<< std::endl;
}
@@ -837,5 +883,6 @@ std::string ClientProxy::Dump() {
return sstream.str();
}
} // namespace connections
} // namespace nearby
+22 -8
View File
@@ -17,12 +17,15 @@
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <vector>
#include "connections/advertising_options.h"
#include "connections/discovery_options.h"
#include "connections/implementation/analytics/analytics_recorder.h"
#include "connections/implementation/proto/offline_wire_formats.pb.h"
#include "connections/listeners.h"
#include "connections/status.h"
#include "connections/strategy.h"
@@ -33,7 +36,6 @@
#include "internal/platform/cancellation_flag.h"
#include "internal/platform/error_code_recorder.h"
#include "internal/platform/mutex.h"
#include "internal/platform/prng.h"
// Prefer using absl:: versions of a set and a map; they tend to be more
// efficient: implementation is using open-addressing hash tables.
#include "absl/container/flat_hash_map.h"
@@ -103,11 +105,10 @@ class ClientProxy final {
const std::string& endpoint_id);
// Proxies to the client's ConnectionListener::OnInitiated() callback.
void OnConnectionInitiated(const std::string& endpoint_id,
const ConnectionResponseInfo& info,
const ConnectionOptions& connection_options,
const ConnectionListener& listener,
const std::string& connection_token);
void OnConnectionInitiated(
const std::string& endpoint_id, const ConnectionResponseInfo& info,
const ConnectionOptions& connection_options,
const ConnectionListener& listener, const std::string& connection_token);
// Proxies to the client's ConnectionListener::OnAccepted() callback.
void OnConnectionAccepted(const std::string& endpoint_id);
@@ -245,6 +246,13 @@ class ClientProxy final {
CancellationFlag* GetCancellationFlag(const NearbyDevice& device);
void CancelEndpoint(const NearbyDevice& device);
const location::nearby::connections::OsInfo& GetLocalOsInfo() const;
std::optional<location::nearby::connections::OsInfo> GetRemoteOsInfo(
absl::string_view endpoint_id) const;
void SetRemoteOsInfo(
absl::string_view endpoint_id,
const location::nearby::connections::OsInfo& remote_os_info);
private:
struct Connection {
// Status: may be either:
@@ -274,6 +282,7 @@ class ClientProxy final {
DiscoveryOptions discovery_options;
AdvertisingOptions advertising_options;
std::string connection_token;
std::optional<location::nearby::connections::OsInfo> os_info;
};
struct AdvertisingInfo {
@@ -297,8 +306,8 @@ class ClientProxy final {
void AppendConnectionStatus(const std::string& endpoint_id,
Connection::Status status_to_append);
const Connection* LookupConnection(const std::string& endpoint_id) const;
Connection* LookupConnection(const std::string& endpoint_id);
const Connection* LookupConnection(absl::string_view endpoint_id) const;
Connection* LookupConnection(absl::string_view endpoint_id);
bool ConnectionStatusMatches(const std::string& endpoint_id,
Connection::Status status) const;
std::vector<std::string> GetMatchingEndpoints(
@@ -308,6 +317,9 @@ class ClientProxy final {
void ScheduleClearLocalHighVisModeCacheEndpointIdAlarm();
void CancelClearLocalHighVisModeCacheEndpointIdAlarm();
location::nearby::connections::OsInfo::OsType OSNameToOsInfoType(
api::OSName osName);
std::string ToString(PayloadProgressInfo::Status status) const;
mutable RecursiveMutex mutex_;
@@ -372,6 +384,8 @@ class ClientProxy final {
// nullptr as no-op.
std::unique_ptr<analytics::AnalyticsRecorder> analytics_recorder_;
std::unique_ptr<ErrorCodeRecorder> error_code_recorder_;
// Local device OS information.
location::nearby::connections::OsInfo local_os_info_;
};
} // namespace connections
@@ -15,6 +15,7 @@
#include "connections/implementation/client_proxy.h"
#include <cstdio>
#include <optional>
#include <string>
#include "gmock/gmock.h"
@@ -36,6 +37,7 @@ namespace nearby {
namespace connections {
namespace {
using ::location::nearby::connections::OsInfo;
using ::testing::MockFunction;
using ::testing::StrictMock;
@@ -897,6 +899,33 @@ TEST_F(ClientProxyTest, LogSessionForResetClientProxy) {
EXPECT_TRUE(client2_.GetAnalyticsRecorder().IsSessionLogged());
}
TEST_F(ClientProxyTest, GetLocalInfoCorrect) {
ClientProxy client;
// Default is g3 test Environment as LINUX.
EXPECT_EQ(client.GetLocalOsInfo().type(), OsInfo::LINUX);
}
TEST_F(ClientProxyTest, GetRemoteInfoNullWithoutConnections) {
Endpoint advertising_endpoint =
StartAdvertising(&client1_, advertising_connection_listener_);
EXPECT_FALSE(client1_.GetRemoteOsInfo(advertising_endpoint.id).has_value());
}
TEST_F(ClientProxyTest, SetRemoteInfoCorrect) {
Endpoint advertising_endpoint =
StartAdvertising(&client1_, advertising_connection_listener_);
OnAdvertisingConnectionInitiated(&client1_, advertising_endpoint);
OsInfo os_info;
os_info.set_type(OsInfo::ANDROID);
client1_.SetRemoteOsInfo(advertising_endpoint.id, os_info);
ASSERT_TRUE(client1_.GetRemoteOsInfo(advertising_endpoint.id).has_value());
EXPECT_EQ(client1_.GetRemoteOsInfo(advertising_endpoint.id).value().type(),
OsInfo::ANDROID);
}
} // namespace
} // namespace connections
} // namespace nearby
@@ -407,12 +407,11 @@ void EndpointManager::RegisterEndpoint(
absl::Milliseconds(connection_options.keep_alive_interval_millis);
absl::Duration keep_alive_timeout =
absl::Milliseconds(connection_options.keep_alive_timeout_millis);
NEARBY_LOGS(INFO) << "Registering endpoint " << endpoint_id
<< " for client " << client->GetClientId()
<< " with keep-alive frame as interval="
<< absl::FormatDuration(keep_alive_interval)
<< ", timeout="
<< absl::FormatDuration(keep_alive_timeout);
NEARBY_LOGS(INFO)
<< "Registering endpoint " << endpoint_id << " for client "
<< client->GetClientId() << " with keep-alive frame as interval="
<< absl::FormatDuration(keep_alive_interval)
<< ", timeout=" << absl::FormatDuration(keep_alive_timeout);
// Pass ownership of channel to EndpointChannelManager
NEARBY_LOGS(INFO) << "Registering endpoint with channel manager: endpoint "
@@ -107,12 +107,12 @@ class EndpointManager {
// Invoked from the different PcpHandler implementations (of which there can
// be only one at a time).
// Blocks until registration is complete.
void RegisterEndpoint(ClientProxy* client, const std::string& endpoint_id,
const ConnectionResponseInfo& info,
const ConnectionOptions& connection_options,
std::unique_ptr<EndpointChannel> channel,
const ConnectionListener& listener,
const std::string& connection_token);
void RegisterEndpoint(
ClientProxy* client, const std::string& endpoint_id,
const ConnectionResponseInfo& info,
const ConnectionOptions& connection_options,
std::unique_ptr<EndpointChannel> channel,
const ConnectionListener& listener, const std::string& connection_token);
// Called when a client explicitly asks to disconnect from this endpoint. In
// this case, we do not notify the client of onDisconnected().
void UnregisterEndpoint(ClientProxy* client, const std::string& endpoint_id);
@@ -31,10 +31,9 @@
#include "connections/implementation/endpoint_channel_manager.h"
#include "connections/implementation/offline_frames.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/exception.h"
#include "internal/platform/count_down_latch.h"
#include "internal/platform/exception.h"
#include "internal/platform/logging.h"
#include "internal/platform/pipe.h"
#include "proto/connections_enums.pb.h"
namespace nearby {
+4 -1
View File
@@ -22,6 +22,7 @@
#include "connections/implementation/offline_frames_validator.h"
#include "connections/status.h"
#include "internal/platform/byte_array.h"
#include "connections/implementation/proto/offline_wire_formats.pb.h"
namespace nearby {
namespace connections {
@@ -36,6 +37,7 @@ using ::location::nearby::connections::ConnectionRequestFrame;
using ::location::nearby::connections::ConnectionResponseFrame;
using ::location::nearby::connections::LocationHint;
using ::location::nearby::connections::OfflineFrame;
using ::location::nearby::connections::OsInfo;
using ::location::nearby::connections::PayloadTransferFrame;
using ::location::nearby::connections::V1Frame;
@@ -110,7 +112,7 @@ ByteArray ForConnectionRequest(const ConnectionInfo& conection_info) {
return ToBytes(std::move(frame));
}
ByteArray ForConnectionResponse(std::int32_t status) {
ByteArray ForConnectionResponse(std::int32_t status, const OsInfo& os_info) {
OfflineFrame frame;
frame.set_version(OfflineFrame::V1);
@@ -125,6 +127,7 @@ ByteArray ForConnectionResponse(std::int32_t status) {
sub_frame->set_response(status == Status::kSuccess
? ConnectionResponseFrame::ACCEPT
: ConnectionResponseFrame::REJECT);
*sub_frame->mutable_os_info() = os_info;
return ToBytes(std::move(frame));
}
+2 -1
View File
@@ -46,7 +46,8 @@ location::nearby::connections::V1Frame::FrameType GetFrameType(
// Builds Connection Request / Response messages.
ByteArray ForConnectionRequest(const ConnectionInfo& conection_info);
ByteArray ForConnectionResponse(std::int32_t status);
ByteArray ForConnectionResponse(
std::int32_t status, const location::nearby::connections::OsInfo& os_info);
// Builds Payload transfer messages.
ByteArray ForDataPayloadTransfer(
@@ -33,6 +33,7 @@ namespace parser {
namespace {
using ::location::nearby::connections::OfflineFrame;
using ::location::nearby::connections::OsInfo;
using ::location::nearby::connections::PayloadTransferFrame;
using ::location::nearby::connections::V1Frame;
using Medium = ::location::nearby::proto::connections::Medium;
@@ -100,7 +101,12 @@ TEST(OfflineFramesTest, CanGenerateConnectionRequest) {
endpoint_name: "XYZ"
endpoint_info: "XYZ"
nonce: 1234
medium_metadata: < supports_5_ghz: true bssid: "FF:FF:FF:FF:FF:FF" ip_address: "8xqT" ap_frequency: 2412 >
medium_metadata: <
supports_5_ghz: true
bssid: "FF:FF:FF:FF:FF:FF"
ip_address: "8xqT"
ap_frequency: 2412
>
mediums: MDNS
mediums: BLUETOOTH
mediums: WIFI_HOTSPOT
@@ -139,9 +145,16 @@ TEST(OfflineFramesTest, CanGenerateConnectionResponse) {
version: V1
v1: <
type: CONNECTION_RESPONSE
connection_response: < status: 1 response: REJECT >
connection_response: <
status: 1
response: REJECT
os_info { type: LINUX }
>
>)pb";
ByteArray bytes = ForConnectionResponse(1);
OsInfo os_info;
os_info.set_type(OsInfo::LINUX);
ByteArray bytes = ForConnectionResponse(1, os_info);
auto response = FromBytes(bytes);
ASSERT_TRUE(response.ok());
OfflineFrame message = FromBytes(bytes).result();
@@ -17,8 +17,6 @@
#include <array>
#include <string>
#include "gmock/gmock.h"
#include "protobuf-matchers/protocol-buffer-matchers.h"
#include "gtest/gtest.h"
#include "absl/strings/string_view.h"
#include "connections/implementation/offline_frames.h"
@@ -31,6 +29,7 @@ namespace parser {
namespace {
using ::location::nearby::connections::OfflineFrame;
using ::location::nearby::connections::OsInfo;
using ::location::nearby::connections::PayloadTransferFrame;
constexpr absl::string_view kEndpointId{"ABC"};
@@ -156,7 +155,8 @@ TEST(OfflineFramesValidatorTest,
ValidatesAsOkWithValidConnectionResponseFrame) {
OfflineFrame offline_frame;
ByteArray bytes = ForConnectionResponse(kStatusAccepted);
OsInfo os_info;
ByteArray bytes = ForConnectionResponse(kStatusAccepted, os_info);
offline_frame.ParseFromString(std::string(bytes));
auto ret_value = EnsureValidOfflineFrame(offline_frame);
@@ -168,7 +168,8 @@ TEST(OfflineFramesValidatorTest,
ValidatesAsFailWithNullConnectionResponseFrame) {
OfflineFrame offline_frame;
ByteArray bytes = ForConnectionResponse(kStatusAccepted);
OsInfo os_info;
ByteArray bytes = ForConnectionResponse(kStatusAccepted, os_info);
offline_frame.ParseFromString(std::string(bytes));
auto* v1_frame = offline_frame.mutable_v1();
@@ -183,7 +184,8 @@ TEST(OfflineFramesValidatorTest,
ValidatesAsFailWithUnexpectedStatusInConnectionResponseFrame) {
OfflineFrame offline_frame;
ByteArray bytes = ForConnectionResponse(-1);
OsInfo os_info;
ByteArray bytes = ForConnectionResponse(-1, os_info);
offline_frame.ParseFromString(std::string(bytes));
auto ret_value = EnsureValidOfflineFrame(offline_frame);
@@ -17,6 +17,7 @@
#include <array>
#include <cinttypes>
#include <memory>
#include <optional>
#include <string>
#include <utility>
@@ -62,7 +62,7 @@ std::string ImplementationPlatform::GetDownloadPath(const std::string& parent_fo
return CppStringFromObjCString([NSTemporaryDirectory() stringByAppendingPathComponent:fileName]);
}
OSName ImplementationPlatform::GetCurrentOS() { return OSName::kiOS; }
OSName ImplementationPlatform::GetCurrentOS() { return OSName::kApple; }
// Atomics:
std::unique_ptr<AtomicBoolean> ImplementationPlatform::CreateAtomicBoolean(bool initial_value) {
+1 -1
View File
@@ -18,7 +18,7 @@
namespace nearby {
namespace api {
enum class OSName { kLinux, kWindows, kiOS, kChromeOS };
enum class OSName { kLinux, kWindows, kApple, kChromeOS, kAndroid };
} // namespace api
} // namespace nearby