mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-14 14:46:12 -04:00
added nearby connections API for linux
This commit is contained in:
+53
-14
@@ -13,7 +13,8 @@
|
||||
# limitations under the License.
|
||||
|
||||
licenses(["notice"])
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
|
||||
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test")
|
||||
load("@rules_cc//cc/private/rules_impl:cc_static_library.bzl", "cc_static_library")
|
||||
|
||||
cc_library(
|
||||
name = "linux_sharing_platform",
|
||||
@@ -46,17 +47,6 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "system_clock_shim",
|
||||
srcs = ["platform/system_clock_shim.cc"],
|
||||
alwayslink = True,
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
"//internal/platform:types",
|
||||
"@com_google_absl//absl/time",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "nearby_sharing_api",
|
||||
srcs = ["nearby_sharing_api.cc"],
|
||||
@@ -65,8 +55,8 @@ cc_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":linux_sharing_platform",
|
||||
":system_clock_shim",
|
||||
"//internal/base:file_path",
|
||||
"//internal/platform/implementation/linux:system_clock",
|
||||
"//sharing:attachments",
|
||||
"//sharing:nearby_sharing_service",
|
||||
"//sharing/analytics",
|
||||
@@ -74,6 +64,25 @@ cc_library(
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "nearby_connections_api",
|
||||
srcs = ["nearby_connections_api.cc"],
|
||||
hdrs = ["nearby_connections_api.h"],
|
||||
alwayslink = True,
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
":linux_sharing_platform",
|
||||
"//internal/base:file_path",
|
||||
"//sharing/internal/public:nearby_context",
|
||||
"//sharing:nearby_sharing_service",
|
||||
],
|
||||
)
|
||||
|
||||
cc_static_library(
|
||||
name = "nearby_sharing_api_static",
|
||||
deps = [":nearby_sharing_api"],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "nearby_sharing_api_shared",
|
||||
linkshared = True,
|
||||
@@ -87,13 +96,43 @@ cc_binary(
|
||||
],
|
||||
deps = [
|
||||
":linux_sharing_platform",
|
||||
":system_clock_shim",
|
||||
"//internal/base:file_path",
|
||||
"//internal/platform/implementation:platform",
|
||||
"//internal/platform/implementation/linux",
|
||||
"//internal/platform/implementation/linux:system_clock",
|
||||
"//sharing:attachments",
|
||||
"//sharing:nearby_sharing_service",
|
||||
"//sharing/analytics",
|
||||
"//sharing/local_device_data",
|
||||
],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "nearby_connections_api_shared",
|
||||
linkshared = True,
|
||||
srcs = [
|
||||
"nearby_connections_api.cc",
|
||||
"nearby_connections_api.h",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
linkopts = [
|
||||
"-Wl,--exclude-libs,ALL",
|
||||
],
|
||||
deps = [
|
||||
":linux_sharing_platform",
|
||||
"//internal/base:file_path",
|
||||
"//internal/platform/implementation:platform",
|
||||
"//internal/platform/implementation/linux",
|
||||
"//sharing/internal/public:nearby_context",
|
||||
"//sharing:nearby_sharing_service",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "nearby_connections_api_test",
|
||||
srcs = ["nearby_connections_api_test.cc"],
|
||||
deps = [
|
||||
":nearby_connections_api",
|
||||
"@com_google_googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -0,0 +1,649 @@
|
||||
#include "sharing/linux/nearby_connections_api.h"
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/time/time.h"
|
||||
#include "internal/base/file_path.h"
|
||||
#include "internal/interop/authentication_status.h"
|
||||
#include "sharing/internal/public/context_impl.h"
|
||||
#include "sharing/linux/platform/linux_sharing_platform.h"
|
||||
#include "sharing/nearby_connections_service.h"
|
||||
#include "sharing/nearby_connections_service_impl.h"
|
||||
|
||||
namespace nearby::sharing {
|
||||
|
||||
namespace {
|
||||
|
||||
using NativeService = nearby::sharing::NearbyConnectionsService;
|
||||
|
||||
NearbyConnectionsApi::StatusCode ToFacadeStatus(Status status) {
|
||||
switch (status) {
|
||||
case Status::kSuccess:
|
||||
return NearbyConnectionsApi::StatusCode::kSuccess;
|
||||
case Status::kError:
|
||||
return NearbyConnectionsApi::StatusCode::kError;
|
||||
case Status::kOutOfOrderApiCall:
|
||||
return NearbyConnectionsApi::StatusCode::kOutOfOrderApiCall;
|
||||
case Status::kAlreadyHaveActiveStrategy:
|
||||
return NearbyConnectionsApi::StatusCode::kAlreadyHaveActiveStrategy;
|
||||
case Status::kAlreadyAdvertising:
|
||||
return NearbyConnectionsApi::StatusCode::kAlreadyAdvertising;
|
||||
case Status::kAlreadyDiscovering:
|
||||
return NearbyConnectionsApi::StatusCode::kAlreadyDiscovering;
|
||||
case Status::kAlreadyListening:
|
||||
return NearbyConnectionsApi::StatusCode::kAlreadyListening;
|
||||
case Status::kEndpointIOError:
|
||||
return NearbyConnectionsApi::StatusCode::kEndpointIOError;
|
||||
case Status::kEndpointUnknown:
|
||||
return NearbyConnectionsApi::StatusCode::kEndpointUnknown;
|
||||
case Status::kConnectionRejected:
|
||||
return NearbyConnectionsApi::StatusCode::kConnectionRejected;
|
||||
case Status::kAlreadyConnectedToEndpoint:
|
||||
return NearbyConnectionsApi::StatusCode::kAlreadyConnectedToEndpoint;
|
||||
case Status::kNotConnectedToEndpoint:
|
||||
return NearbyConnectionsApi::StatusCode::kNotConnectedToEndpoint;
|
||||
case Status::kBluetoothError:
|
||||
return NearbyConnectionsApi::StatusCode::kBluetoothError;
|
||||
case Status::kBleError:
|
||||
return NearbyConnectionsApi::StatusCode::kBleError;
|
||||
case Status::kWifiLanError:
|
||||
return NearbyConnectionsApi::StatusCode::kWifiLanError;
|
||||
case Status::kPayloadUnknown:
|
||||
return NearbyConnectionsApi::StatusCode::kPayloadUnknown;
|
||||
case Status::kReset:
|
||||
return NearbyConnectionsApi::StatusCode::kReset;
|
||||
case Status::kTimeout:
|
||||
return NearbyConnectionsApi::StatusCode::kTimeout;
|
||||
case Status::kUnknown:
|
||||
return NearbyConnectionsApi::StatusCode::kUnknown;
|
||||
case Status::kNextValue:
|
||||
break;
|
||||
}
|
||||
return NearbyConnectionsApi::StatusCode::kUnknown;
|
||||
}
|
||||
|
||||
NearbyConnectionsApi::AuthenticationStatus ToFacadeAuthenticationStatus(
|
||||
::nearby::AuthenticationStatus status) {
|
||||
switch (status) {
|
||||
case ::nearby::AuthenticationStatus::kUnknown:
|
||||
return NearbyConnectionsApi::AuthenticationStatus::kUnknown;
|
||||
case ::nearby::AuthenticationStatus::kSuccess:
|
||||
return NearbyConnectionsApi::AuthenticationStatus::kSuccess;
|
||||
case ::nearby::AuthenticationStatus::kFailure:
|
||||
return NearbyConnectionsApi::AuthenticationStatus::kFailure;
|
||||
}
|
||||
return NearbyConnectionsApi::AuthenticationStatus::kUnknown;
|
||||
}
|
||||
|
||||
NearbyConnectionsApi::DistanceInfo ToFacadeDistanceInfo(
|
||||
nearby::sharing::DistanceInfo distance_info) {
|
||||
switch (distance_info) {
|
||||
case nearby::sharing::DistanceInfo::kUnknown:
|
||||
return NearbyConnectionsApi::DistanceInfo::kUnknown;
|
||||
case nearby::sharing::DistanceInfo::kVeryClose:
|
||||
return NearbyConnectionsApi::DistanceInfo::kVeryClose;
|
||||
case nearby::sharing::DistanceInfo::kClose:
|
||||
return NearbyConnectionsApi::DistanceInfo::kClose;
|
||||
case nearby::sharing::DistanceInfo::kFar:
|
||||
return NearbyConnectionsApi::DistanceInfo::kFar;
|
||||
}
|
||||
return NearbyConnectionsApi::DistanceInfo::kUnknown;
|
||||
}
|
||||
|
||||
NearbyConnectionsApi::Medium ToFacadeMedium(nearby::sharing::Medium medium) {
|
||||
switch (medium) {
|
||||
case nearby::sharing::Medium::kUnknown:
|
||||
return NearbyConnectionsApi::Medium::kUnknown;
|
||||
case nearby::sharing::Medium::kMdns:
|
||||
return NearbyConnectionsApi::Medium::kMdns;
|
||||
case nearby::sharing::Medium::kBluetooth:
|
||||
return NearbyConnectionsApi::Medium::kBluetooth;
|
||||
case nearby::sharing::Medium::kWifiHotspot:
|
||||
return NearbyConnectionsApi::Medium::kWifiHotspot;
|
||||
case nearby::sharing::Medium::kBle:
|
||||
return NearbyConnectionsApi::Medium::kBle;
|
||||
case nearby::sharing::Medium::kWifiLan:
|
||||
return NearbyConnectionsApi::Medium::kWifiLan;
|
||||
case nearby::sharing::Medium::kWifiAware:
|
||||
return NearbyConnectionsApi::Medium::kWifiAware;
|
||||
case nearby::sharing::Medium::kNfc:
|
||||
return NearbyConnectionsApi::Medium::kNfc;
|
||||
case nearby::sharing::Medium::kWifiDirect:
|
||||
return NearbyConnectionsApi::Medium::kWifiDirect;
|
||||
case nearby::sharing::Medium::kWebRtc:
|
||||
return NearbyConnectionsApi::Medium::kWebRtc;
|
||||
case nearby::sharing::Medium::kBleL2Cap:
|
||||
return NearbyConnectionsApi::Medium::kBleL2Cap;
|
||||
}
|
||||
return NearbyConnectionsApi::Medium::kUnknown;
|
||||
}
|
||||
|
||||
nearby::sharing::Strategy ToNativeStrategy(
|
||||
NearbyConnectionsApi::Strategy strategy) {
|
||||
switch (strategy) {
|
||||
case NearbyConnectionsApi::Strategy::kP2pCluster:
|
||||
return nearby::sharing::Strategy::kP2pCluster;
|
||||
case NearbyConnectionsApi::Strategy::kP2pStar:
|
||||
return nearby::sharing::Strategy::kP2pStar;
|
||||
case NearbyConnectionsApi::Strategy::kP2pPointToPoint:
|
||||
return nearby::sharing::Strategy::kP2pPointToPoint;
|
||||
}
|
||||
return nearby::sharing::Strategy::kP2pCluster;
|
||||
}
|
||||
|
||||
nearby::sharing::MediumSelection ToNativeMediumSelection(
|
||||
const NearbyConnectionsApi::MediumSelection& selection) {
|
||||
nearby::sharing::MediumSelection native_selection;
|
||||
native_selection.bluetooth = selection.bluetooth;
|
||||
native_selection.ble = selection.ble;
|
||||
native_selection.web_rtc = selection.web_rtc;
|
||||
native_selection.wifi_lan = selection.wifi_lan;
|
||||
native_selection.wifi_hotspot = selection.wifi_hotspot;
|
||||
return native_selection;
|
||||
}
|
||||
|
||||
nearby::sharing::AdvertisingOptions ToNativeAdvertisingOptions(
|
||||
const NearbyConnectionsApi::AdvertisingOptions& options) {
|
||||
nearby::sharing::AdvertisingOptions native_options;
|
||||
native_options.strategy = ToNativeStrategy(options.strategy);
|
||||
native_options.allowed_mediums =
|
||||
ToNativeMediumSelection(options.allowed_mediums);
|
||||
native_options.auto_upgrade_bandwidth = options.auto_upgrade_bandwidth;
|
||||
native_options.enforce_topology_constraints =
|
||||
options.enforce_topology_constraints;
|
||||
native_options.enable_bluetooth_listening =
|
||||
options.enable_bluetooth_listening;
|
||||
native_options.enable_webrtc_listening = options.enable_webrtc_listening;
|
||||
native_options.use_stable_endpoint_id = options.use_stable_endpoint_id;
|
||||
native_options.force_new_endpoint_id = options.force_new_endpoint_id;
|
||||
native_options.fast_advertisement_service_uuid =
|
||||
nearby::sharing::Uuid(options.fast_advertisement_service_uuid);
|
||||
return native_options;
|
||||
}
|
||||
|
||||
nearby::sharing::DiscoveryOptions ToNativeDiscoveryOptions(
|
||||
const NearbyConnectionsApi::DiscoveryOptions& options) {
|
||||
nearby::sharing::DiscoveryOptions native_options;
|
||||
native_options.strategy = ToNativeStrategy(options.strategy);
|
||||
native_options.allowed_mediums =
|
||||
ToNativeMediumSelection(options.allowed_mediums);
|
||||
if (options.has_fast_advertisement_service_uuid) {
|
||||
native_options.fast_advertisement_service_uuid =
|
||||
nearby::sharing::Uuid(options.fast_advertisement_service_uuid.uuid);
|
||||
}
|
||||
native_options.is_out_of_band_connection =
|
||||
options.is_out_of_band_connection;
|
||||
if (options.has_alternate_service_uuid) {
|
||||
native_options.alternate_service_uuid = options.alternate_service_uuid;
|
||||
}
|
||||
return native_options;
|
||||
}
|
||||
|
||||
nearby::sharing::ConnectionOptions ToNativeConnectionOptions(
|
||||
const NearbyConnectionsApi::ConnectionOptions& options) {
|
||||
nearby::sharing::ConnectionOptions native_options;
|
||||
native_options.allowed_mediums =
|
||||
ToNativeMediumSelection(options.allowed_mediums);
|
||||
if (!options.remote_bluetooth_mac_address.empty()) {
|
||||
native_options.remote_bluetooth_mac_address =
|
||||
options.remote_bluetooth_mac_address;
|
||||
}
|
||||
if (options.has_keep_alive_interval_millis &&
|
||||
options.keep_alive_interval_millis >= 0) {
|
||||
native_options.keep_alive_interval =
|
||||
absl::Milliseconds(options.keep_alive_interval_millis);
|
||||
}
|
||||
if (options.has_keep_alive_timeout_millis &&
|
||||
options.keep_alive_timeout_millis >= 0) {
|
||||
native_options.keep_alive_timeout =
|
||||
absl::Milliseconds(options.keep_alive_timeout_millis);
|
||||
}
|
||||
native_options.non_disruptive_hotspot_mode =
|
||||
options.non_disruptive_hotspot_mode;
|
||||
return native_options;
|
||||
}
|
||||
|
||||
NearbyConnectionsApi::ConnectionInfo ToFacadeConnectionInfo(
|
||||
const nearby::sharing::ConnectionInfo& info) {
|
||||
NearbyConnectionsApi::ConnectionInfo facade_info;
|
||||
facade_info.authentication_token = info.authentication_token;
|
||||
facade_info.raw_authentication_token = info.raw_authentication_token;
|
||||
facade_info.endpoint_info = info.endpoint_info;
|
||||
facade_info.is_incoming_connection = info.is_incoming_connection;
|
||||
facade_info.connection_layer_status =
|
||||
ToFacadeStatus(info.connection_layer_status);
|
||||
facade_info.authentication_status =
|
||||
ToFacadeAuthenticationStatus(info.authentication_status);
|
||||
return facade_info;
|
||||
}
|
||||
|
||||
NearbyConnectionsApi::DiscoveredEndpointInfo ToFacadeDiscoveredEndpointInfo(
|
||||
const nearby::sharing::DiscoveredEndpointInfo& info) {
|
||||
NearbyConnectionsApi::DiscoveredEndpointInfo facade_info;
|
||||
facade_info.endpoint_info = info.endpoint_info;
|
||||
facade_info.service_id = info.service_id;
|
||||
return facade_info;
|
||||
}
|
||||
|
||||
NearbyConnectionsApi::PayloadStatus ToFacadePayloadStatus(
|
||||
nearby::sharing::PayloadStatus status) {
|
||||
switch (status) {
|
||||
case nearby::sharing::PayloadStatus::kSuccess:
|
||||
return NearbyConnectionsApi::PayloadStatus::kSuccess;
|
||||
case nearby::sharing::PayloadStatus::kFailure:
|
||||
return NearbyConnectionsApi::PayloadStatus::kFailure;
|
||||
case nearby::sharing::PayloadStatus::kInProgress:
|
||||
return NearbyConnectionsApi::PayloadStatus::kInProgress;
|
||||
case nearby::sharing::PayloadStatus::kCanceled:
|
||||
return NearbyConnectionsApi::PayloadStatus::kCanceled;
|
||||
}
|
||||
return NearbyConnectionsApi::PayloadStatus::kFailure;
|
||||
}
|
||||
|
||||
NearbyConnectionsApi::Payload ToFacadePayload(
|
||||
const nearby::sharing::Payload& payload) {
|
||||
NearbyConnectionsApi::Payload facade_payload;
|
||||
facade_payload.id = payload.id;
|
||||
switch (payload.content.type) {
|
||||
case nearby::sharing::PayloadContent::Type::kBytes:
|
||||
facade_payload.type = NearbyConnectionsApi::PayloadType::kBytes;
|
||||
facade_payload.bytes = payload.content.bytes_payload.bytes;
|
||||
break;
|
||||
case nearby::sharing::PayloadContent::Type::kFile:
|
||||
facade_payload.type = NearbyConnectionsApi::PayloadType::kFile;
|
||||
facade_payload.file_path =
|
||||
payload.content.file_payload.file_path.ToString();
|
||||
facade_payload.parent_folder = payload.content.file_payload.parent_folder;
|
||||
break;
|
||||
case nearby::sharing::PayloadContent::Type::kUnknown:
|
||||
case nearby::sharing::PayloadContent::Type::kStream:
|
||||
facade_payload.type = NearbyConnectionsApi::PayloadType::kUnknown;
|
||||
break;
|
||||
}
|
||||
return facade_payload;
|
||||
}
|
||||
|
||||
std::unique_ptr<nearby::sharing::Payload> ToNativePayload(
|
||||
NearbyConnectionsApi::Payload payload) {
|
||||
switch (payload.type) {
|
||||
case NearbyConnectionsApi::PayloadType::kBytes:
|
||||
return std::make_unique<nearby::sharing::Payload>(
|
||||
payload.id, std::move(payload.bytes));
|
||||
case NearbyConnectionsApi::PayloadType::kFile:
|
||||
return std::make_unique<nearby::sharing::Payload>(
|
||||
payload.id, FilePath(payload.file_path), payload.parent_folder);
|
||||
case NearbyConnectionsApi::PayloadType::kUnknown:
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
NearbyConnectionsApi::PayloadTransferUpdate ToFacadePayloadTransferUpdate(
|
||||
const nearby::sharing::PayloadTransferUpdate& update) {
|
||||
NearbyConnectionsApi::PayloadTransferUpdate facade_update;
|
||||
facade_update.payload_id = update.payload_id;
|
||||
facade_update.status = ToFacadePayloadStatus(update.status);
|
||||
facade_update.total_bytes = update.total_bytes;
|
||||
facade_update.bytes_transferred = update.bytes_transferred;
|
||||
return facade_update;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class NearbyConnectionsApi::Impl {
|
||||
public:
|
||||
struct ListenerState {
|
||||
std::mutex mutex;
|
||||
NearbyConnectionsApi::Listener listener;
|
||||
};
|
||||
|
||||
Impl()
|
||||
: platform(),
|
||||
context(platform),
|
||||
service(std::make_unique<NearbyConnectionsServiceImpl>(
|
||||
context.GetConnectivityManager(), /*event_logger=*/nullptr)),
|
||||
listener_state(std::make_shared<ListenerState>()) {}
|
||||
|
||||
static NearbyConnectionsApi::Listener CopyListener(
|
||||
const std::shared_ptr<ListenerState>& listener_state) {
|
||||
std::scoped_lock lock(listener_state->mutex);
|
||||
return listener_state->listener;
|
||||
}
|
||||
|
||||
static NativeService::ConnectionListener BuildConnectionListener(
|
||||
const std::shared_ptr<ListenerState>& listener_state) {
|
||||
NativeService::ConnectionListener listener;
|
||||
listener.initiated_cb =
|
||||
[listener_state](const std::string& endpoint_id,
|
||||
const nearby::sharing::ConnectionInfo& info) {
|
||||
NearbyConnectionsApi::Listener listener_copy =
|
||||
CopyListener(listener_state);
|
||||
if (!listener_copy.connection_initiated_cb) {
|
||||
return;
|
||||
}
|
||||
listener_copy.connection_initiated_cb(endpoint_id,
|
||||
ToFacadeConnectionInfo(info));
|
||||
};
|
||||
listener.accepted_cb = [listener_state](const std::string& endpoint_id) {
|
||||
NearbyConnectionsApi::Listener listener_copy =
|
||||
CopyListener(listener_state);
|
||||
if (listener_copy.connection_accepted_cb) {
|
||||
listener_copy.connection_accepted_cb(endpoint_id);
|
||||
}
|
||||
};
|
||||
listener.rejected_cb = [listener_state](const std::string& endpoint_id,
|
||||
Status status) {
|
||||
NearbyConnectionsApi::Listener listener_copy =
|
||||
CopyListener(listener_state);
|
||||
if (listener_copy.connection_rejected_cb) {
|
||||
listener_copy.connection_rejected_cb(endpoint_id,
|
||||
ToFacadeStatus(status));
|
||||
}
|
||||
};
|
||||
listener.disconnected_cb = [listener_state](const std::string& endpoint_id) {
|
||||
NearbyConnectionsApi::Listener listener_copy =
|
||||
CopyListener(listener_state);
|
||||
if (listener_copy.disconnected_cb) {
|
||||
listener_copy.disconnected_cb(endpoint_id);
|
||||
}
|
||||
};
|
||||
listener.bandwidth_changed_cb =
|
||||
[listener_state](const std::string& endpoint_id,
|
||||
nearby::sharing::Medium medium) {
|
||||
NearbyConnectionsApi::Listener listener_copy =
|
||||
CopyListener(listener_state);
|
||||
if (listener_copy.bandwidth_changed_cb) {
|
||||
listener_copy.bandwidth_changed_cb(endpoint_id,
|
||||
ToFacadeMedium(medium));
|
||||
}
|
||||
};
|
||||
return listener;
|
||||
}
|
||||
|
||||
static NativeService::DiscoveryListener BuildDiscoveryListener(
|
||||
const std::shared_ptr<ListenerState>& listener_state) {
|
||||
NativeService::DiscoveryListener listener;
|
||||
listener.endpoint_found_cb =
|
||||
[listener_state](const std::string& endpoint_id,
|
||||
const nearby::sharing::DiscoveredEndpointInfo& info) {
|
||||
NearbyConnectionsApi::Listener listener_copy =
|
||||
CopyListener(listener_state);
|
||||
if (listener_copy.endpoint_found_cb) {
|
||||
listener_copy.endpoint_found_cb(
|
||||
endpoint_id, ToFacadeDiscoveredEndpointInfo(info));
|
||||
}
|
||||
};
|
||||
listener.endpoint_lost_cb = [listener_state](const std::string& endpoint_id) {
|
||||
NearbyConnectionsApi::Listener listener_copy =
|
||||
CopyListener(listener_state);
|
||||
if (listener_copy.endpoint_lost_cb) {
|
||||
listener_copy.endpoint_lost_cb(endpoint_id);
|
||||
}
|
||||
};
|
||||
listener.endpoint_distance_changed_cb =
|
||||
[listener_state](const std::string& endpoint_id,
|
||||
nearby::sharing::DistanceInfo distance_info) {
|
||||
NearbyConnectionsApi::Listener listener_copy =
|
||||
CopyListener(listener_state);
|
||||
if (listener_copy.endpoint_distance_changed_cb) {
|
||||
listener_copy.endpoint_distance_changed_cb(
|
||||
endpoint_id, ToFacadeDistanceInfo(distance_info));
|
||||
}
|
||||
};
|
||||
return listener;
|
||||
}
|
||||
|
||||
static NativeService::PayloadListener BuildPayloadListener(
|
||||
const std::shared_ptr<ListenerState>& listener_state) {
|
||||
NativeService::PayloadListener listener;
|
||||
listener.payload_cb = [listener_state](absl::string_view endpoint_id,
|
||||
nearby::sharing::Payload payload) {
|
||||
NearbyConnectionsApi::Listener listener_copy =
|
||||
CopyListener(listener_state);
|
||||
if (listener_copy.payload_received_cb) {
|
||||
listener_copy.payload_received_cb(std::string(endpoint_id),
|
||||
ToFacadePayload(payload));
|
||||
}
|
||||
};
|
||||
listener.payload_progress_cb =
|
||||
[listener_state](
|
||||
absl::string_view endpoint_id,
|
||||
const nearby::sharing::PayloadTransferUpdate& update) {
|
||||
NearbyConnectionsApi::Listener listener_copy =
|
||||
CopyListener(listener_state);
|
||||
if (listener_copy.payload_transfer_update_cb) {
|
||||
listener_copy.payload_transfer_update_cb(
|
||||
std::string(endpoint_id), ToFacadePayloadTransferUpdate(update));
|
||||
}
|
||||
};
|
||||
return listener;
|
||||
}
|
||||
|
||||
LinuxSharingPlatform platform;
|
||||
::nearby::ContextImpl context;
|
||||
std::unique_ptr<NativeService> service;
|
||||
std::shared_ptr<ListenerState> listener_state;
|
||||
};
|
||||
|
||||
NearbyConnectionsApi::NearbyConnectionsApi() : impl_(std::make_unique<Impl>()) {}
|
||||
|
||||
NearbyConnectionsApi::~NearbyConnectionsApi() = default;
|
||||
|
||||
NearbyConnectionsApi::NearbyConnectionsApi(NearbyConnectionsApi&&) noexcept =
|
||||
default;
|
||||
|
||||
NearbyConnectionsApi& NearbyConnectionsApi::operator=(
|
||||
NearbyConnectionsApi&&) noexcept = default;
|
||||
|
||||
void NearbyConnectionsApi::SetListener(Listener listener) {
|
||||
std::scoped_lock lock(impl_->listener_state->mutex);
|
||||
impl_->listener_state->listener = std::move(listener);
|
||||
}
|
||||
|
||||
void NearbyConnectionsApi::StartAdvertising(
|
||||
const std::string& service_id, const std::vector<uint8_t>& endpoint_info,
|
||||
const AdvertisingOptions& options,
|
||||
std::function<void(StatusCode)> callback) {
|
||||
impl_->service->StartAdvertising(
|
||||
service_id, endpoint_info, ToNativeAdvertisingOptions(options),
|
||||
Impl::BuildConnectionListener(impl_->listener_state),
|
||||
[callback = std::move(callback)](Status status) mutable {
|
||||
if (callback) {
|
||||
callback(ToFacadeStatus(status));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NearbyConnectionsApi::StopAdvertising(
|
||||
const std::string& service_id, std::function<void(StatusCode)> callback) {
|
||||
impl_->service->StopAdvertising(
|
||||
service_id, [callback = std::move(callback)](Status status) mutable {
|
||||
if (callback) {
|
||||
callback(ToFacadeStatus(status));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NearbyConnectionsApi::StartDiscovery(
|
||||
const std::string& service_id, const DiscoveryOptions& options,
|
||||
std::function<void(StatusCode)> callback) {
|
||||
impl_->service->StartDiscovery(
|
||||
service_id, ToNativeDiscoveryOptions(options),
|
||||
Impl::BuildDiscoveryListener(impl_->listener_state),
|
||||
[callback = std::move(callback)](Status status) mutable {
|
||||
if (callback) {
|
||||
callback(ToFacadeStatus(status));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NearbyConnectionsApi::StopDiscovery(
|
||||
const std::string& service_id, std::function<void(StatusCode)> callback) {
|
||||
impl_->service->StopDiscovery(
|
||||
service_id, [callback = std::move(callback)](Status status) mutable {
|
||||
if (callback) {
|
||||
callback(ToFacadeStatus(status));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NearbyConnectionsApi::RequestConnection(
|
||||
const std::string& service_id, const std::vector<uint8_t>& endpoint_info,
|
||||
const std::string& endpoint_id, const ConnectionOptions& options,
|
||||
std::function<void(StatusCode)> callback) {
|
||||
impl_->service->RequestConnection(
|
||||
service_id, endpoint_info, endpoint_id, ToNativeConnectionOptions(options),
|
||||
Impl::BuildConnectionListener(impl_->listener_state),
|
||||
[callback = std::move(callback)](Status status) mutable {
|
||||
if (callback) {
|
||||
callback(ToFacadeStatus(status));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NearbyConnectionsApi::DisconnectFromEndpoint(
|
||||
const std::string& service_id, const std::string& endpoint_id,
|
||||
std::function<void(StatusCode)> callback) {
|
||||
impl_->service->DisconnectFromEndpoint(
|
||||
service_id, endpoint_id,
|
||||
[callback = std::move(callback)](Status status) mutable {
|
||||
if (callback) {
|
||||
callback(ToFacadeStatus(status));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NearbyConnectionsApi::SendPayload(
|
||||
const std::string& service_id, const std::vector<std::string>& endpoint_ids,
|
||||
Payload payload, std::function<void(StatusCode)> callback) {
|
||||
std::unique_ptr<nearby::sharing::Payload> native_payload =
|
||||
ToNativePayload(std::move(payload));
|
||||
if (native_payload == nullptr) {
|
||||
if (callback) {
|
||||
callback(StatusCode::kError);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
impl_->service->SendPayload(
|
||||
service_id, endpoint_ids, std::move(native_payload),
|
||||
[callback = std::move(callback)](Status status) mutable {
|
||||
if (callback) {
|
||||
callback(ToFacadeStatus(status));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NearbyConnectionsApi::CancelPayload(
|
||||
const std::string& service_id, int64_t payload_id,
|
||||
std::function<void(StatusCode)> callback) {
|
||||
impl_->service->CancelPayload(
|
||||
service_id, payload_id,
|
||||
[callback = std::move(callback)](Status status) mutable {
|
||||
if (callback) {
|
||||
callback(ToFacadeStatus(status));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NearbyConnectionsApi::InitiateBandwidthUpgrade(
|
||||
const std::string& service_id, const std::string& endpoint_id,
|
||||
std::function<void(StatusCode)> callback) {
|
||||
impl_->service->InitiateBandwidthUpgrade(
|
||||
service_id, endpoint_id,
|
||||
[callback = std::move(callback)](Status status) mutable {
|
||||
if (callback) {
|
||||
callback(ToFacadeStatus(status));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NearbyConnectionsApi::AcceptConnection(
|
||||
const std::string& service_id, const std::string& endpoint_id,
|
||||
std::function<void(StatusCode)> callback) {
|
||||
impl_->service->AcceptConnection(
|
||||
service_id, endpoint_id, Impl::BuildPayloadListener(impl_->listener_state),
|
||||
[callback = std::move(callback)](Status status) mutable {
|
||||
if (callback) {
|
||||
callback(ToFacadeStatus(status));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NearbyConnectionsApi::StopAllEndpoints(
|
||||
std::function<void(StatusCode)> callback) {
|
||||
impl_->service->StopAllEndpoints(
|
||||
[callback = std::move(callback)](Status status) mutable {
|
||||
if (callback) {
|
||||
callback(ToFacadeStatus(status));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NearbyConnectionsApi::SetCustomSavePath(
|
||||
const std::string& path, std::function<void(StatusCode)> callback) {
|
||||
impl_->service->SetCustomSavePath(
|
||||
path, [callback = std::move(callback)](Status status) mutable {
|
||||
if (callback) {
|
||||
callback(ToFacadeStatus(status));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void NearbyConnectionsApi::OverrideSavePath(const std::string& endpoint_id,
|
||||
const std::string& path) {
|
||||
impl_->service->OverrideSavePath(endpoint_id, path);
|
||||
}
|
||||
|
||||
std::string NearbyConnectionsApi::Dump() const { return impl_->service->Dump(); }
|
||||
|
||||
std::string NearbyConnectionsApi::StatusCodeToString(StatusCode status) {
|
||||
switch (status) {
|
||||
case StatusCode::kSuccess:
|
||||
return "Success";
|
||||
case StatusCode::kError:
|
||||
return "Error";
|
||||
case StatusCode::kOutOfOrderApiCall:
|
||||
return "OutOfOrderApiCall";
|
||||
case StatusCode::kAlreadyHaveActiveStrategy:
|
||||
return "AlreadyHaveActiveStrategy";
|
||||
case StatusCode::kAlreadyAdvertising:
|
||||
return "AlreadyAdvertising";
|
||||
case StatusCode::kAlreadyDiscovering:
|
||||
return "AlreadyDiscovering";
|
||||
case StatusCode::kAlreadyListening:
|
||||
return "AlreadyListening";
|
||||
case StatusCode::kEndpointIOError:
|
||||
return "EndpointIOError";
|
||||
case StatusCode::kEndpointUnknown:
|
||||
return "EndpointUnknown";
|
||||
case StatusCode::kConnectionRejected:
|
||||
return "ConnectionRejected";
|
||||
case StatusCode::kAlreadyConnectedToEndpoint:
|
||||
return "AlreadyConnectedToEndpoint";
|
||||
case StatusCode::kNotConnectedToEndpoint:
|
||||
return "NotConnectedToEndpoint";
|
||||
case StatusCode::kBluetoothError:
|
||||
return "BluetoothError";
|
||||
case StatusCode::kBleError:
|
||||
return "BleError";
|
||||
case StatusCode::kWifiLanError:
|
||||
return "WifiLanError";
|
||||
case StatusCode::kPayloadUnknown:
|
||||
return "PayloadUnknown";
|
||||
case StatusCode::kReset:
|
||||
return "Reset";
|
||||
case StatusCode::kTimeout:
|
||||
return "Timeout";
|
||||
case StatusCode::kUnknown:
|
||||
return "Unknown";
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
} // namespace nearby::sharing
|
||||
@@ -0,0 +1,268 @@
|
||||
// Copyright 2026
|
||||
//
|
||||
// Thin app-facing API for NearbyConnectionsService on Linux that avoids
|
||||
// exposing internal Nearby headers to external consumers.
|
||||
|
||||
#ifndef SHARING_LINUX_NEARBY_CONNECTIONS_API_H_
|
||||
#define SHARING_LINUX_NEARBY_CONNECTIONS_API_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace nearby {
|
||||
namespace sharing {
|
||||
|
||||
class __attribute__((visibility("default"))) NearbyConnectionsApi {
|
||||
public:
|
||||
enum class StatusCode {
|
||||
kSuccess = 0,
|
||||
kError = 1,
|
||||
kOutOfOrderApiCall = 2,
|
||||
kAlreadyHaveActiveStrategy = 3,
|
||||
kAlreadyAdvertising = 4,
|
||||
kAlreadyDiscovering = 5,
|
||||
kAlreadyListening = 6,
|
||||
kEndpointIOError = 7,
|
||||
kEndpointUnknown = 8,
|
||||
kConnectionRejected = 9,
|
||||
kAlreadyConnectedToEndpoint = 10,
|
||||
kNotConnectedToEndpoint = 11,
|
||||
kBluetoothError = 12,
|
||||
kBleError = 13,
|
||||
kWifiLanError = 14,
|
||||
kPayloadUnknown = 15,
|
||||
kReset = 16,
|
||||
kTimeout = 17,
|
||||
kUnknown = 18,
|
||||
};
|
||||
|
||||
enum class Strategy {
|
||||
kP2pCluster = 0,
|
||||
kP2pStar = 1,
|
||||
kP2pPointToPoint = 2,
|
||||
};
|
||||
|
||||
enum class Medium {
|
||||
kUnknown = 0,
|
||||
kMdns = 1,
|
||||
kBluetooth = 2,
|
||||
kWifiHotspot = 3,
|
||||
kBle = 4,
|
||||
kWifiLan = 5,
|
||||
kWifiAware = 6,
|
||||
kNfc = 7,
|
||||
kWifiDirect = 8,
|
||||
kWebRtc = 9,
|
||||
kBleL2Cap = 10,
|
||||
};
|
||||
|
||||
enum class DistanceInfo {
|
||||
kUnknown = 1,
|
||||
kVeryClose = 2,
|
||||
kClose = 3,
|
||||
kFar = 4,
|
||||
};
|
||||
|
||||
enum class AuthenticationStatus {
|
||||
kUnknown = 0,
|
||||
kSuccess = 1,
|
||||
kFailure = 2,
|
||||
};
|
||||
|
||||
enum class PayloadType {
|
||||
kUnknown = 0,
|
||||
kBytes = 1,
|
||||
kFile = 2,
|
||||
};
|
||||
|
||||
enum class PayloadStatus {
|
||||
kSuccess = 0,
|
||||
kFailure = 1,
|
||||
kInProgress = 2,
|
||||
kCanceled = 3,
|
||||
};
|
||||
|
||||
struct Uuid {
|
||||
std::string uuid;
|
||||
};
|
||||
|
||||
struct MediumSelection {
|
||||
bool bluetooth = true;
|
||||
bool ble = true;
|
||||
bool web_rtc = true;
|
||||
bool wifi_lan = true;
|
||||
bool wifi_hotspot = true;
|
||||
};
|
||||
|
||||
struct AdvertisingOptions {
|
||||
Strategy strategy = Strategy::kP2pCluster;
|
||||
MediumSelection allowed_mediums;
|
||||
bool auto_upgrade_bandwidth = true;
|
||||
bool enforce_topology_constraints = true;
|
||||
bool enable_bluetooth_listening = false;
|
||||
bool enable_webrtc_listening = false;
|
||||
bool use_stable_endpoint_id = false;
|
||||
bool force_new_endpoint_id = false;
|
||||
std::string fast_advertisement_service_uuid;
|
||||
};
|
||||
|
||||
struct DiscoveryOptions {
|
||||
Strategy strategy = Strategy::kP2pCluster;
|
||||
MediumSelection allowed_mediums;
|
||||
bool has_fast_advertisement_service_uuid = false;
|
||||
Uuid fast_advertisement_service_uuid;
|
||||
bool is_out_of_band_connection = false;
|
||||
bool has_alternate_service_uuid = false;
|
||||
uint16_t alternate_service_uuid = 0;
|
||||
};
|
||||
|
||||
struct ConnectionOptions {
|
||||
MediumSelection allowed_mediums;
|
||||
std::vector<uint8_t> remote_bluetooth_mac_address;
|
||||
bool has_keep_alive_interval_millis = false;
|
||||
int64_t keep_alive_interval_millis = 0;
|
||||
bool has_keep_alive_timeout_millis = false;
|
||||
int64_t keep_alive_timeout_millis = 0;
|
||||
bool non_disruptive_hotspot_mode = false;
|
||||
};
|
||||
|
||||
struct ConnectionInfo {
|
||||
std::string authentication_token;
|
||||
std::vector<uint8_t> raw_authentication_token;
|
||||
std::vector<uint8_t> endpoint_info;
|
||||
bool is_incoming_connection = false;
|
||||
StatusCode connection_layer_status = StatusCode::kUnknown;
|
||||
AuthenticationStatus authentication_status =
|
||||
AuthenticationStatus::kUnknown;
|
||||
};
|
||||
|
||||
struct DiscoveredEndpointInfo {
|
||||
std::vector<uint8_t> endpoint_info;
|
||||
std::string service_id;
|
||||
};
|
||||
|
||||
struct PayloadTransferUpdate {
|
||||
int64_t payload_id = 0;
|
||||
PayloadStatus status = PayloadStatus::kInProgress;
|
||||
uint64_t total_bytes = 0;
|
||||
uint64_t bytes_transferred = 0;
|
||||
};
|
||||
|
||||
struct Payload {
|
||||
int64_t id = 0;
|
||||
PayloadType type = PayloadType::kUnknown;
|
||||
std::vector<uint8_t> bytes;
|
||||
std::string file_path;
|
||||
std::string parent_folder;
|
||||
|
||||
static Payload FromBytes(int64_t id, std::vector<uint8_t> bytes) {
|
||||
Payload payload;
|
||||
payload.id = id;
|
||||
payload.type = PayloadType::kBytes;
|
||||
payload.bytes = std::move(bytes);
|
||||
return payload;
|
||||
}
|
||||
|
||||
static Payload FromFile(int64_t id, std::string file_path,
|
||||
std::string parent_folder = {}) {
|
||||
Payload payload;
|
||||
payload.id = id;
|
||||
payload.type = PayloadType::kFile;
|
||||
payload.file_path = std::move(file_path);
|
||||
payload.parent_folder = std::move(parent_folder);
|
||||
return payload;
|
||||
}
|
||||
};
|
||||
|
||||
struct Listener {
|
||||
std::function<void(const std::string&, const DiscoveredEndpointInfo&)>
|
||||
endpoint_found_cb;
|
||||
std::function<void(const std::string&)> endpoint_lost_cb;
|
||||
std::function<void(const std::string&, DistanceInfo)>
|
||||
endpoint_distance_changed_cb;
|
||||
|
||||
std::function<void(const std::string&, const ConnectionInfo&)>
|
||||
connection_initiated_cb;
|
||||
std::function<void(const std::string&)> connection_accepted_cb;
|
||||
std::function<void(const std::string&, StatusCode)> connection_rejected_cb;
|
||||
std::function<void(const std::string&)> disconnected_cb;
|
||||
std::function<void(const std::string&, Medium)> bandwidth_changed_cb;
|
||||
|
||||
std::function<void(const std::string&, const Payload&)>
|
||||
payload_received_cb;
|
||||
std::function<void(const std::string&, const PayloadTransferUpdate&)>
|
||||
payload_transfer_update_cb;
|
||||
};
|
||||
|
||||
NearbyConnectionsApi();
|
||||
~NearbyConnectionsApi();
|
||||
|
||||
NearbyConnectionsApi(const NearbyConnectionsApi&) = delete;
|
||||
NearbyConnectionsApi& operator=(const NearbyConnectionsApi&) = delete;
|
||||
NearbyConnectionsApi(NearbyConnectionsApi&&) noexcept;
|
||||
NearbyConnectionsApi& operator=(NearbyConnectionsApi&&) noexcept;
|
||||
|
||||
void SetListener(Listener listener);
|
||||
|
||||
void StartAdvertising(const std::string& service_id,
|
||||
const std::vector<uint8_t>& endpoint_info,
|
||||
const AdvertisingOptions& options,
|
||||
std::function<void(StatusCode)> callback);
|
||||
void StopAdvertising(const std::string& service_id,
|
||||
std::function<void(StatusCode)> callback);
|
||||
|
||||
void StartDiscovery(const std::string& service_id,
|
||||
const DiscoveryOptions& options,
|
||||
std::function<void(StatusCode)> callback);
|
||||
void StopDiscovery(const std::string& service_id,
|
||||
std::function<void(StatusCode)> callback);
|
||||
|
||||
void RequestConnection(const std::string& service_id,
|
||||
const std::vector<uint8_t>& endpoint_info,
|
||||
const std::string& endpoint_id,
|
||||
const ConnectionOptions& options,
|
||||
std::function<void(StatusCode)> callback);
|
||||
|
||||
void DisconnectFromEndpoint(const std::string& service_id,
|
||||
const std::string& endpoint_id,
|
||||
std::function<void(StatusCode)> callback);
|
||||
|
||||
void SendPayload(const std::string& service_id,
|
||||
const std::vector<std::string>& endpoint_ids,
|
||||
Payload payload,
|
||||
std::function<void(StatusCode)> callback);
|
||||
void CancelPayload(const std::string& service_id, int64_t payload_id,
|
||||
std::function<void(StatusCode)> callback);
|
||||
|
||||
void InitiateBandwidthUpgrade(const std::string& service_id,
|
||||
const std::string& endpoint_id,
|
||||
std::function<void(StatusCode)> callback);
|
||||
|
||||
void AcceptConnection(const std::string& service_id,
|
||||
const std::string& endpoint_id,
|
||||
std::function<void(StatusCode)> callback);
|
||||
|
||||
void StopAllEndpoints(std::function<void(StatusCode)> callback);
|
||||
|
||||
void SetCustomSavePath(const std::string& path,
|
||||
std::function<void(StatusCode)> callback);
|
||||
void OverrideSavePath(const std::string& endpoint_id,
|
||||
const std::string& path);
|
||||
|
||||
std::string Dump() const;
|
||||
|
||||
static std::string StatusCodeToString(StatusCode status);
|
||||
|
||||
private:
|
||||
class Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
} // namespace sharing
|
||||
} // namespace nearby
|
||||
|
||||
#endif // SHARING_LINUX_NEARBY_CONNECTIONS_API_H_
|
||||
@@ -0,0 +1,44 @@
|
||||
#include "sharing/linux/nearby_connections_api.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace nearby::sharing {
|
||||
namespace {
|
||||
|
||||
TEST(NearbyConnectionsApiTest, PayloadFromBytesSetsFields) {
|
||||
NearbyConnectionsApi::Payload payload =
|
||||
NearbyConnectionsApi::Payload::FromBytes(42, {1, 2, 3});
|
||||
|
||||
EXPECT_EQ(payload.id, 42);
|
||||
EXPECT_EQ(payload.type, NearbyConnectionsApi::PayloadType::kBytes);
|
||||
EXPECT_EQ(payload.bytes, (std::vector<uint8_t>{1, 2, 3}));
|
||||
EXPECT_TRUE(payload.file_path.empty());
|
||||
}
|
||||
|
||||
TEST(NearbyConnectionsApiTest, PayloadFromFileSetsFields) {
|
||||
NearbyConnectionsApi::Payload payload =
|
||||
NearbyConnectionsApi::Payload::FromFile(7, "/tmp/test.txt", "tmp");
|
||||
|
||||
EXPECT_EQ(payload.id, 7);
|
||||
EXPECT_EQ(payload.type, NearbyConnectionsApi::PayloadType::kFile);
|
||||
EXPECT_EQ(payload.file_path, "/tmp/test.txt");
|
||||
EXPECT_EQ(payload.parent_folder, "tmp");
|
||||
EXPECT_TRUE(payload.bytes.empty());
|
||||
}
|
||||
|
||||
TEST(NearbyConnectionsApiTest, StatusCodeToStringCoversRepresentativeValues) {
|
||||
EXPECT_EQ(NearbyConnectionsApi::StatusCodeToString(
|
||||
NearbyConnectionsApi::StatusCode::kSuccess),
|
||||
"Success");
|
||||
EXPECT_EQ(NearbyConnectionsApi::StatusCodeToString(
|
||||
NearbyConnectionsApi::StatusCode::kConnectionRejected),
|
||||
"ConnectionRejected");
|
||||
EXPECT_EQ(NearbyConnectionsApi::StatusCodeToString(
|
||||
NearbyConnectionsApi::StatusCode::kUnknown),
|
||||
"Unknown");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace nearby::sharing
|
||||
Reference in New Issue
Block a user