switched from using custom linux fork of nearby_connections_service_linux and nearby_sharing_service_linux, switched to google's implementation of nearby sharing service. with appropriate stubs for missing parts

This commit is contained in:
Lasan Mahaliyana
2026-03-16 00:16:38 +05:30
parent f62348a4e5
commit 21b2c4c3c1
35 changed files with 367 additions and 4154 deletions
+4 -6
View File
@@ -232,8 +232,7 @@ cc_library(
"//internal/base:file_path",
"//internal/base:files",
"//internal/platform:types",
"//location/nearby/sharing/lib/sync:sync_config_prefs_cc_proto",
"//location/nearby/sharing/lib/sync:sync_manager",
"//sharing/linux/stubs:sync",
"//proto:sharing_enums_cc_proto",
"//sharing/analytics",
"//sharing/certificates",
@@ -384,9 +383,8 @@ cc_library(
"//internal/platform:types",
"//internal/platform/implementation:account_manager",
"//internal/platform/implementation:types",
"//location/nearby/sharing/lib/rpc:grpc_async_client_factory",
"//location/nearby/sharing/lib/rpc:sharing_rpc_client",
"//location/nearby/sharing/lib/sync:sync_manager",
"//sharing/linux/stubs:rpc",
"//sharing/linux/stubs:sync",
"//proto:sharing_enums_cc_proto",
"//sharing/analytics",
"//sharing/certificates",
@@ -634,7 +632,7 @@ cc_test(
"//internal/platform/implementation:signin_attempt",
"//internal/test",
"//internal/test:mocks",
"//location/nearby/sharing/lib/rpc:fake_nearby_share_client",
"//sharing/linux/stubs:rpc",
"//sharing/analytics",
"//sharing/certificates",
"//sharing/certificates:test_support",
+5 -9
View File
@@ -42,26 +42,23 @@ cc_library(
],
visibility = ["//visibility:public"],
deps = [
"//google/nearby/identity/v1:resources_cc_proto",
"//google/nearby/identity/v1:rpcs_cc_proto",
"//google/protobuf:timestamp_cc_proto",
"//internal/base",
"//internal/base:file_path",
"//internal/crypto_cros",
"//internal/platform:mac_address",
"//internal/platform:types",
"//internal/platform/implementation:account_manager",
"//location/nearby/sharing/lib/rpc:sharing_rpc_client",
"//sharing/internal/api:platform",
"//sharing/internal/base",
"//sharing/internal/public:logging",
"//sharing/internal/public:pref_names",
"//sharing/internal/public:types",
"//sharing/linux/stubs:highway_fingerprint",
"//sharing/linux/stubs:rpc",
"//sharing/local_device_data",
"//sharing/proto:enums_cc_proto",
"//sharing/proto:share_cc_proto",
"//sharing/scheduling",
"//util/hash:highway_fingerprint",
"@com_google_absl//absl/algorithm",
"@com_google_absl//absl/base:nullability",
"@com_google_absl//absl/container:btree",
@@ -75,6 +72,7 @@ cc_library(
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:span",
"@com_google_protobuf//:protobuf",
],
)
@@ -97,10 +95,10 @@ cc_library(
"//internal/base:bluetooth_address",
"//internal/base:file_path",
"//internal/crypto_cros",
"//location/nearby/sharing/lib/rpc:sharing_rpc_client",
"//sharing/common:enum",
"//sharing/internal/api:platform",
"//sharing/internal/public:types",
"//sharing/linux/stubs:rpc",
"//sharing/local_device_data",
"//sharing/proto:enums_cc_proto",
"//sharing/proto:share_cc_proto",
@@ -124,13 +122,11 @@ cc_test(
deps = [
":certificates",
":test_support",
"//google/nearby/identity/v1:resources_cc_proto",
"//google/nearby/identity/v1:rpcs_cc_proto",
"//internal/platform:mac_address",
"//internal/platform/implementation:account_manager",
"//internal/platform/implementation:platform_impl",
"//internal/test",
"//location/nearby/sharing/lib/rpc:fake_nearby_share_client",
"//sharing/linux/stubs:rpc",
"//sharing/common:enum",
"//sharing/internal/api:mock_sharing_platform",
"//sharing/internal/api:platform",
@@ -23,7 +23,6 @@
#include <utility>
#include <vector>
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "internal/base/file_path.h"
#include "sharing/certificates/nearby_share_certificate_manager.h"
#include "sharing/certificates/nearby_share_encrypted_metadata_key.h"
@@ -31,6 +30,11 @@
#include "sharing/certificates/test_util.h"
#include "sharing/internal/public/context.h"
#include "sharing/local_device_data/nearby_share_local_device_data_manager.h"
#if defined(__linux__)
#include "sharing/linux/stubs/sharing_rpc_client.h"
#else
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#endif
#include "sharing/proto/enums.pb.h"
#include "sharing/proto/rpc_resources.pb.h"
@@ -24,7 +24,6 @@
#include <string>
#include <vector>
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "internal/base/file_path.h"
#include "sharing/certificates/nearby_share_certificate_manager.h"
#include "sharing/certificates/nearby_share_certificate_manager_impl.h"
@@ -33,6 +32,11 @@
#include "sharing/internal/public/context.h"
#include "sharing/local_device_data/nearby_share_local_device_data_manager.h"
#include "sharing/proto/rpc_resources.pb.h"
#if defined(__linux__)
#include "sharing/linux/stubs/sharing_rpc_client.h"
#else
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#endif
namespace nearby {
namespace sharing {
@@ -28,10 +28,7 @@
#include <utility>
#include <vector>
#include "google/nearby/identity/v1/resources.pb.h"
#include "google/nearby/identity/v1/rpcs.pb.h"
#include "google/protobuf/timestamp.pb.h"
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "absl/algorithm/algorithm.h"
#include "absl/base/nullability.h"
#include "absl/container/flat_hash_map.h"
@@ -63,6 +60,16 @@
#include "sharing/internal/public/logging.h"
#include "sharing/internal/public/pref_names.h"
#include "sharing/local_device_data/nearby_share_local_device_data_manager.h"
#if defined(__linux__)
#include "sharing/linux/stubs/highway_fingerprint.h"
#include "sharing/linux/stubs/identity_rpc_types.h"
#include "sharing/linux/stubs/sharing_rpc_client.h"
#else
#include "google/nearby/identity/v1/resources.pb.h"
#include "google/nearby/identity/v1/rpcs.pb.h"
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "util/hash/highway_fingerprint.h"
#endif
#include "sharing/proto/certificate_rpc.pb.h"
#include "sharing/proto/encrypted_metadata.pb.h"
#include "sharing/proto/enums.pb.h"
@@ -70,7 +77,6 @@
#include "sharing/proto/timestamp.pb.h"
#include "sharing/scheduling/nearby_share_scheduler.h"
#include "sharing/scheduling/nearby_share_scheduler_factory.h"
#include "util/hash/highway_fingerprint.h"
namespace nearby {
namespace sharing {
@@ -23,7 +23,6 @@
#include <utility>
#include <vector>
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "absl/base/nullability.h"
#include "absl/functional/any_invocable.h"
#include "absl/status/statusor.h"
@@ -43,8 +42,15 @@
#include "sharing/proto/enums.pb.h"
#include "sharing/proto/rpc_resources.pb.h"
namespace google::nearby::identity::v1 {
class PublishDeviceRequest;
} // namespace google::nearby::identity::v1
namespace nearby {
namespace sharing {
namespace api {
class IdentityRpcClient;
} // namespace api
class NearbyShareScheduler;
+2 -2
View File
@@ -43,9 +43,9 @@ cc_library(
":contacts_interface",
"//internal/platform:types",
"//internal/platform/implementation:account_manager",
"//location/nearby/sharing/lib/rpc:sharing_rpc_client",
"//sharing/internal/public:logging",
"//sharing/internal/public:types",
"//sharing/linux/stubs:rpc",
"//sharing/proto:share_cc_proto",
"@com_google_absl//absl/base:nullability",
"@com_google_absl//absl/status:statusor",
@@ -73,7 +73,7 @@ cc_test(
"//internal/platform/implementation:account_manager",
"//internal/platform/implementation:platform_impl",
"//internal/test",
"//location/nearby/sharing/lib/rpc:fake_nearby_share_client",
"//sharing/linux/stubs:rpc",
"//sharing/internal/test:nearby_test",
"//sharing/local_device_data:test_support",
"//sharing/proto:share_cc_proto",
@@ -23,7 +23,6 @@
#include <utility>
#include <vector>
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "absl/base/nullability.h"
#include "absl/status/statusor.h"
#include "absl/synchronization/notification.h"
@@ -31,6 +30,11 @@
#include "sharing/contacts/nearby_share_contact_manager.h"
#include "sharing/internal/public/context.h"
#include "sharing/internal/public/logging.h"
#if defined(__linux__)
#include "sharing/linux/stubs/sharing_rpc_client.h"
#else
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#endif
#include "sharing/proto/contact_rpc.pb.h"
#include "sharing/proto/rpc_resources.pb.h"
@@ -17,7 +17,6 @@
#include <memory>
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "absl/base/nullability.h"
#include "internal/platform/implementation/account_manager.h"
#include "internal/platform/task_runner.h"
@@ -26,12 +25,15 @@
namespace nearby {
namespace sharing {
namespace api {
class SharingRpcClient;
} // namespace api
class NearbyShareContactManagerImpl : public NearbyShareContactManager {
public:
NearbyShareContactManagerImpl(
Context* absl_nonnull context, AccountManager& account_manager,
nearby::sharing::api::SharingRpcClient* absl_nonnull nearby_client);
api::SharingRpcClient* absl_nonnull nearby_client);
~NearbyShareContactManagerImpl() override = default;
@@ -40,7 +42,7 @@ class NearbyShareContactManagerImpl : public NearbyShareContactManager {
void GetContacts(ContactsCallback callback) override;
AccountManager& account_manager_;
nearby::sharing::api::SharingRpcClient& nearby_share_client_;
api::SharingRpcClient& nearby_share_client_;
std::unique_ptr<TaskRunner> executor_ = nullptr;
};
+5 -2
View File
@@ -24,8 +24,6 @@
#include <utility>
#include <vector>
#include "location/nearby/sharing/lib/sync/sync_config_prefs.pb.h"
#include "location/nearby/sharing/lib/sync/sync_manager.h"
#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
#include "absl/time/time.h"
@@ -36,6 +34,11 @@
#include "sharing/attachment_container.h"
#include "sharing/constants.h"
#include "sharing/file_attachment.h"
#if defined(__linux__)
#include "sharing/linux/stubs/sync_manager.h"
#else
#include "location/nearby/sharing/lib/sync/sync_manager.h"
#endif
#include "sharing/internal/public/logging.h"
#include "sharing/nearby_connection.h"
#include "sharing/nearby_connections_manager.h"
+2 -1
View File
@@ -21,7 +21,6 @@
#include <string>
#include <vector>
#include "location/nearby/sharing/lib/sync/sync_manager.h"
#include "absl/functional/any_invocable.h"
#include "internal/base/file_path.h"
#include "internal/platform/clock.h"
@@ -38,6 +37,8 @@
namespace nearby::sharing {
class SyncManager;
// Class that represents a single incoming share session.
// This class is thread-compatible.
class IncomingShareSession : public ShareSession {
+1 -3
View File
@@ -33,7 +33,6 @@ cc_library(
visibility = [
"//location/nearby/analytics/cpp/logging:__pkg__",
"//location/nearby/cpp/sharing:__subpackages__",
"//location/nearby/sharing/lib:__subpackages__",
"//location/nearby/sharing/sdk/test_client:__pkg__",
"//sharing:__subpackages__",
],
@@ -42,9 +41,8 @@ cc_library(
"//internal/platform:mac_address",
"//internal/platform:types",
"//internal/platform/implementation:account_manager",
"//location/nearby/sharing/lib/sync:sync_binding_prefs_cc_proto",
"//location/nearby/sharing/lib/sync:sync_config_prefs_cc_proto",
"//sharing/proto:share_cc_proto",
"//sharing/proto:wire_format_cc_proto",
"@com_google_absl//absl/functional:any_invocable",
"@com_google_absl//absl/strings:string_view",
"@com_google_absl//absl/time",
+16 -2
View File
@@ -32,6 +32,7 @@
#define NEARBY_HAS_SYNC_CONFIG_PREFS_PROTO 1
#endif // __has_include("location/nearby/sharing/lib/sync/sync_config_prefs.pb.h")
#endif // defined(__has_include)
#include "sharing/proto/wire_format.pb.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
@@ -41,8 +42,21 @@
namespace nearby::sharing::sync {
class SyncConfigPrefs {
public:
bool ParseFromString(const std::string&) { return false; }
std::string SerializeAsString() const { return {}; }
bool ParseFromString(const std::string& serialized) {
return sync_config_.ParseFromString(serialized);
}
std::string SerializeAsString() const {
return sync_config_.SerializeAsString();
}
const nearby::sharing::service::proto::SyncConfig& sync_config() const {
return sync_config_;
}
nearby::sharing::service::proto::SyncConfig* mutable_sync_config() {
return &sync_config_;
}
private:
nearby::sharing::service::proto::SyncConfig sync_config_;
};
} // namespace nearby::sharing::sync
#endif // NEARBY_HAS_SYNC_CONFIG_PREFS_PROTO
+36 -7
View File
@@ -15,31 +15,60 @@
#ifndef THIRD_PARTY_NEARBY_SHARING_INTERNAL_BASE_UTF_STRING_CONVERSIONS_H_
#define THIRD_PARTY_NEARBY_SHARING_INTERNAL_BASE_UTF_STRING_CONVERSIONS_H_
#include <string>
#include <string_view>
#if defined(GITHUB_BUILD)
// Stub out string conversion functions for github builds.
namespace nearby::utils {
bool IsStringUtf8(std::string_view str) { return true; }
inline bool IsStringUtf8(std::string_view str) {
static_cast<void>(str);
return true;
}
void TruncateUtf8ToByteSize(const std::string& input, size_t byte_size,
std::string* output) {}
inline void TruncateUtf8ToByteSize(const std::string& input, size_t byte_size,
std::string* output) {
if (output == nullptr) {
return;
}
*output = input.substr(0, byte_size);
}
} // namespace nearby::utils
#elif defined(NEARBY_CHROMIUM)
// Forward to chromium implementations.
#include "base/strings/string_util.h"
namespace nearby::utils {
bool IsStringUtf8(std::string_view str) {
inline bool IsStringUtf8(std::string_view str) {
return base::IsStringUTF8(str);
}
void TruncateUtf8ToByteSize(const std::string& input, size_t byte_size,
std::string* output) {
inline void TruncateUtf8ToByteSize(const std::string& input, size_t byte_size,
std::string* output) {
base::TruncateUTF8ToByteSize(input, byte_size, output);
}
} // namespace nearby::utils
#else // defined(GITHUB_BUILD)
#elif defined(__has_include) && \
__has_include("sharing/internal/base/strings/utf_string_conversions.h")
#include "sharing/internal/base/strings/utf_string_conversions.h" // IWYU pragma: export
#else
namespace nearby::utils {
inline bool IsStringUtf8(std::string_view str) {
static_cast<void>(str);
return true;
}
inline void TruncateUtf8ToByteSize(const std::string& input, size_t byte_size,
std::string* output) {
if (output == nullptr) {
return;
}
*output = input.substr(0, byte_size);
}
} // namespace nearby::utils
#endif // defined(GITHUB_BUILD)
#endif // THIRD_PARTY_NEARBY_SHARING_INTERNAL_BASE_UTF_STRING_CONVERSIONS_H_
-1
View File
@@ -22,7 +22,6 @@ cc_library(
hdrs = [
"pref_names.h",
],
compatible_with = ["//buildenv/target:non_prod"],
visibility = ["//visibility:public"],
deps = [
"@com_google_absl//absl/strings",
-2
View File
@@ -40,8 +40,6 @@ cc_library(
"//internal/platform:mac_address",
"//internal/platform:types",
"//internal/test",
"//location/nearby/sharing/lib/sync:sync_binding_prefs_cc_proto",
"//location/nearby/sharing/lib/sync:sync_config_prefs_cc_proto",
"//sharing/internal/api:platform",
"//sharing/internal/public:pref_names",
"//sharing/internal/public:types",
@@ -22,8 +22,6 @@
#include <variant>
#include <vector>
#include "location/nearby/sharing/lib/sync/sync_binding_prefs.pb.h"
#include "location/nearby/sharing/lib/sync/sync_config_prefs.pb.h"
#include "absl/container/flat_hash_map.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
@@ -23,8 +23,6 @@
#include <variant>
#include <vector>
#include "location/nearby/sharing/lib/sync/sync_binding_prefs.pb.h"
#include "location/nearby/sharing/lib/sync/sync_config_prefs.pb.h"
#include "absl/base/thread_annotations.h"
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
+35 -152
View File
@@ -13,62 +13,47 @@
# limitations under the License.
licenses(["notice"])
load("@rules_cc//cc:defs.bzl", "cc_library", "cc_binary")
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
cc_library(
name = "nearby_connections_service_linux",
srcs = ["nearby_connections_service_linux.cc"],
hdrs = [
"nearby_connections_service_linux.h",
"//sharing:nearby_connections_service.h",
],
visibility = ["//visibility:public"],
name = "linux_sharing_platform",
srcs = ["platform/linux_sharing_platform.cc"],
hdrs = ["platform/linux_sharing_platform.h"],
visibility = ["//visibility:private"],
deps = [
"//connections:core",
"//connections:core_types",
"//internal/base:file_path",
"//internal/base:files",
"//internal/platform:base",
"//internal/platform:logging",
"//internal/platform:mac_address",
"//internal/platform:types",
"//internal/platform:uuid",
"//internal/platform/implementation:account_manager",
"//internal/platform/implementation:platform",
"//internal/platform/implementation:signin_attempt",
"//internal/platform/implementation:types",
"//internal/platform/implementation/linux",
# "//internal/platform/implementation/linux:crypto",
"//sharing:connection_types",
"//sharing/internal/api:platform",
"//sharing/internal/public:pref_names",
"//sharing/proto:share_cc_proto",
"@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/strings:string_view",
"@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/synchronization",
"@com_google_absl//absl/time",
"@com_google_absl//absl/types:span",
"@nlohmann_json//:json",
],
)
cc_library(
name = "nearby_connections_qt_facade",
srcs = ["nearby_connections_qt_facade.cc"],
hdrs = ["nearby_connections_qt_facade.h"],
name = "system_clock_shim",
srcs = ["platform/system_clock_shim.cc"],
alwayslink = True,
visibility = ["//visibility:public"],
visibility = ["//visibility:private"],
deps = [
":nearby_connections_service_linux",
"//internal/base:file_path",
],
)
cc_binary(
name = "nearby_connections_service_linux_shared",
linkshared = True,
srcs = [
"nearby_connections_qt_facade.cc",
"nearby_connections_qt_facade.h",
],
visibility = ["//visibility:public"],
linkopts = [
"-Wl,--exclude-libs,ALL",
],
deps = [
":nearby_connections_service_linux",
"//internal/base:file_path",
"//internal/platform/implementation:platform",
"//internal/platform/implementation/linux",
"//internal/platform:types",
"@com_google_absl//absl/time",
],
)
@@ -79,9 +64,13 @@ cc_library(
alwayslink = True,
visibility = ["//visibility:public"],
deps = [
":nearby_sharing_service_linux",
":linux_sharing_platform",
":system_clock_shim",
"//internal/base:file_path",
"//sharing:attachments",
"//sharing:nearby_sharing_service",
"//sharing/analytics",
"//sharing/local_device_data",
],
)
@@ -97,120 +86,14 @@ cc_binary(
"-Wl,--exclude-libs,ALL",
],
deps = [
":nearby_sharing_service_linux",
":linux_sharing_platform",
":system_clock_shim",
"//internal/base:file_path",
"//internal/platform/implementation:platform",
"//internal/platform/implementation/linux",
"//sharing:attachments",
],
)
cc_binary(
name = "app",
srcs = [
"qml_tray_app/main.cpp",
"qml_tray_app/nearby_tray_controller.cc"
],
copts = [
"-I/usr/include/qt6",
"-I/usr/include/qt6/QtCore",
],
linkopts = [
"-lQt6Core",
],
)
cc_library(
name = "nearby_sharing_service_linux",
srcs = [
"nearby_sharing_service_linux.cc",
"//sharing:nearby_sharing_service.cc",
"//sharing:nearby_sharing_settings.cc",
"//sharing:thread_timer.cc",
"//sharing:transfer_metadata.cc",
"//sharing:transfer_metadata_builder.cc",
"//sharing/analytics:analytics_recorder.cc",
"//sharing/certificates:common.cc",
"//sharing/certificates:nearby_share_certificate_manager.cc",
"//sharing/certificates:nearby_share_decrypted_public_certificate.cc",
"//sharing/certificates:nearby_share_encrypted_metadata_key.cc",
"//sharing/certificates:nearby_share_private_certificate.cc",
"//sharing/common:nearby_share_prefs.cc",
"//sharing/local_device_data:nearby_share_local_device_data_manager.cc",
],
hdrs = [
"nearby_sharing_service_linux.h",
"//sharing:nearby_sharing_service.h",
"//sharing:nearby_sharing_settings.h",
"//sharing:share_target_discovered_callback.h",
"//sharing:thread_timer.h",
"//sharing:transfer_metadata.h",
"//sharing:transfer_metadata_builder.h",
"//sharing:transfer_update_callback.h",
"//sharing/analytics:analytics_device_settings.h",
"//sharing/analytics:analytics_information.h",
"//sharing/analytics:analytics_recorder.h",
"//sharing/certificates:common.h",
"//sharing/certificates:constants.h",
"//sharing/certificates:nearby_share_certificate_manager.h",
"//sharing/certificates:nearby_share_decrypted_public_certificate.h",
"//sharing/certificates:nearby_share_encrypted_metadata_key.h",
"//sharing/certificates:nearby_share_private_certificate.h",
"//sharing/common:nearby_share_prefs.h",
"//sharing/internal/api:bluetooth_adapter.h",
"//sharing/internal/api:fast_init_ble_beacon.h",
"//sharing/internal/api:fast_initiation_manager.h",
"//sharing/internal/api:preference_manager.h",
"//sharing/internal/api:private_certificate_data.h",
"//sharing/internal/public:connectivity_manager.h",
"//sharing/internal/public:context.h",
"//sharing/internal/public:pref_names.h",
"//sharing/local_device_data:nearby_share_local_device_data_manager.h",
],
visibility = ["//visibility:public"],
linkopts = [
"-lssl",
"-lcrypto"
],
deps = [
"//connections:core",
"//connections:core_types",
"//internal/platform:base",
"//internal/platform:comm",
"//internal/platform:types",
"//internal/platform/implementation:platform",
"//internal/platform/implementation/linux",
"//internal/platform/implementation/linux:crypto",
"//sharing:attachments",
"//sharing:types",
"//sharing/proto:share_cc_proto",
# "@boringssl//:crypto",
"@com_google_absl//absl/strings",
],
)
cc_binary(
name = "nearby_sharing_app",
srcs = ["nearby_sharing_app.cc"],
visibility = ["//visibility:public"],
deps = [
":nearby_sharing_service_linux",
"//internal/platform:base",
"//sharing:attachments",
"//sharing:types",
"@com_google_absl//absl/strings",
],
)
cc_binary(
name = "simple_example",
srcs = ["simple_example.cc"],
visibility = ["//visibility:public"],
deps = [
":nearby_sharing_service_linux",
"//internal/platform:base",
"//sharing:attachments",
"//sharing:types",
"@com_google_absl//absl/strings",
"//sharing:nearby_sharing_service",
"//sharing/analytics",
"//sharing/local_device_data",
],
)
@@ -1,473 +0,0 @@
#include "sharing/linux/nearby_connections_qt_facade.h"
#include <atomic>
#include <utility>
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
#include "internal/base/file_path.h"
#include "internal/flags/nearby_flags.h"
#include "sharing/linux/nearby_connections_service_linux.h"
#include "sharing/nearby_connections_service.h"
#include "sharing/nearby_connections_types.h"
namespace nearby::sharing {
namespace {
using Facade = NearbyConnectionsQtFacade;
using NativeService = nearby::sharing::NearbyConnectionsService;
std::atomic<int64_t> g_next_payload_id{1};
int64_t NextPayloadId() { return g_next_payload_id.fetch_add(1); }
std::string DecodePeerName(const std::vector<uint8_t>& endpoint_info) {
if (endpoint_info.empty()) {
return {};
}
std::string decoded(endpoint_info.begin(), endpoint_info.end());
while (!decoded.empty() && decoded.back() == '\0') {
decoded.pop_back();
}
return decoded;
}
Facade::Status ToFacadeStatus(nearby::sharing::Status status) {
switch (status) {
case nearby::sharing::Status::kSuccess:
return Facade::Status::kSuccess;
case nearby::sharing::Status::kError:
return Facade::Status::kError;
case nearby::sharing::Status::kOutOfOrderApiCall:
return Facade::Status::kOutOfOrderApiCall;
case nearby::sharing::Status::kAlreadyHaveActiveStrategy:
return Facade::Status::kAlreadyHaveActiveStrategy;
case nearby::sharing::Status::kAlreadyAdvertising:
return Facade::Status::kAlreadyAdvertising;
case nearby::sharing::Status::kAlreadyDiscovering:
return Facade::Status::kAlreadyDiscovering;
case nearby::sharing::Status::kAlreadyListening:
return Facade::Status::kAlreadyListening;
case nearby::sharing::Status::kEndpointIOError:
return Facade::Status::kEndpointIOError;
case nearby::sharing::Status::kEndpointUnknown:
return Facade::Status::kEndpointUnknown;
case nearby::sharing::Status::kConnectionRejected:
return Facade::Status::kConnectionRejected;
case nearby::sharing::Status::kAlreadyConnectedToEndpoint:
return Facade::Status::kAlreadyConnectedToEndpoint;
case nearby::sharing::Status::kNotConnectedToEndpoint:
return Facade::Status::kNotConnectedToEndpoint;
case nearby::sharing::Status::kBluetoothError:
return Facade::Status::kBluetoothError;
case nearby::sharing::Status::kBleError:
return Facade::Status::kBleError;
case nearby::sharing::Status::kWifiLanError:
return Facade::Status::kWifiLanError;
case nearby::sharing::Status::kPayloadUnknown:
return Facade::Status::kPayloadUnknown;
case nearby::sharing::Status::kReset:
return Facade::Status::kReset;
case nearby::sharing::Status::kTimeout:
return Facade::Status::kTimeout;
case nearby::sharing::Status::kUnknown:
return Facade::Status::kUnknown;
case nearby::sharing::Status::kNextValue:
return Facade::Status::kNextValue;
}
return Facade::Status::kUnknown;
}
Facade::PayloadStatus ToFacadePayloadStatus(nearby::sharing::PayloadStatus status) {
switch (status) {
case nearby::sharing::kSuccess:
return Facade::PayloadStatus::kSuccess;
case nearby::sharing::kFailure:
return Facade::PayloadStatus::kFailure;
case nearby::sharing::kInProgress:
return Facade::PayloadStatus::kInProgress;
case nearby::sharing::kCanceled:
return Facade::PayloadStatus::kCanceled;
}
return Facade::PayloadStatus::kFailure;
}
Facade::Medium ToFacadeMedium(nearby::sharing::Medium medium) {
switch (medium) {
case nearby::sharing::Medium::kUnknown:
return Facade::Medium::kUnknown;
case nearby::sharing::Medium::kMdns:
return Facade::Medium::kMdns;
case nearby::sharing::Medium::kBluetooth:
return Facade::Medium::kBluetooth;
case nearby::sharing::Medium::kWifiHotspot:
return Facade::Medium::kWifiHotspot;
case nearby::sharing::Medium::kBle:
return Facade::Medium::kBle;
case nearby::sharing::Medium::kWifiLan:
return Facade::Medium::kWifiLan;
case nearby::sharing::Medium::kWifiAware:
return Facade::Medium::kWifiAware;
case nearby::sharing::Medium::kNfc:
return Facade::Medium::kNfc;
case nearby::sharing::Medium::kWifiDirect:
return Facade::Medium::kWifiDirect;
case nearby::sharing::Medium::kWebRtc:
return Facade::Medium::kWebRtc;
case nearby::sharing::Medium::kBleL2Cap:
return Facade::Medium::kBleL2Cap;
}
return Facade::Medium::kUnknown;
}
Facade::DistanceInfo ToFacadeDistance(nearby::sharing::DistanceInfo distance) {
switch (distance) {
case nearby::sharing::DistanceInfo::kUnknown:
return Facade::DistanceInfo::kUnknown;
case nearby::sharing::DistanceInfo::kVeryClose:
return Facade::DistanceInfo::kVeryClose;
case nearby::sharing::DistanceInfo::kClose:
return Facade::DistanceInfo::kClose;
case nearby::sharing::DistanceInfo::kFar:
return Facade::DistanceInfo::kFar;
}
return Facade::DistanceInfo::kUnknown;
}
nearby::sharing::Strategy ToNativeStrategy(Facade::Strategy strategy) {
switch (strategy) {
case Facade::Strategy::kP2pCluster:
return nearby::sharing::Strategy::kP2pCluster;
case Facade::Strategy::kP2pStar:
return nearby::sharing::Strategy::kP2pStar;
case Facade::Strategy::kP2pPointToPoint:
return nearby::sharing::Strategy::kP2pPointToPoint;
}
return nearby::sharing::Strategy::kP2pCluster;
}
nearby::sharing::MediumSelection ToNativeMediumSelection(
const Facade::MediumSelection& selection) {
return nearby::sharing::MediumSelection(selection.bluetooth, selection.ble,
selection.web_rtc,
selection.wifi_lan,
selection.wifi_hotspot);
}
nearby::sharing::AdvertisingOptions ToNativeAdvertisingOptions(
const Facade::AdvertisingOptions& options) {
nearby::sharing::AdvertisingOptions native;
native.strategy = ToNativeStrategy(options.strategy);
native.allowed_mediums = ToNativeMediumSelection(options.allowed_mediums);
native.auto_upgrade_bandwidth = options.auto_upgrade_bandwidth;
native.enforce_topology_constraints = options.enforce_topology_constraints;
native.enable_bluetooth_listening = options.enable_bluetooth_listening;
return native;
}
nearby::sharing::DiscoveryOptions ToNativeDiscoveryOptions(
const Facade::DiscoveryOptions& options) {
nearby::sharing::DiscoveryOptions native;
native.strategy = ToNativeStrategy(options.strategy);
native.allowed_mediums = ToNativeMediumSelection(options.allowed_mediums);
return native;
}
nearby::sharing::ConnectionOptions ToNativeConnectionOptions(
const Facade::ConnectionOptions& options) {
nearby::sharing::ConnectionOptions native;
native.allowed_mediums = ToNativeMediumSelection(options.allowed_mediums);
native.non_disruptive_hotspot_mode = options.non_disruptive_hotspot_mode;
return native;
}
std::function<void(nearby::sharing::Status)> ToNativeStatusCallback(
std::function<void(Facade::Status)> callback) {
if (!callback) {
return {};
}
return [cb = std::move(callback)](nearby::sharing::Status status) {
cb(ToFacadeStatus(status));
};
}
NativeService::ConnectionListener ToNativeConnectionListener(
Facade::ConnectionListener listener) {
NativeService::ConnectionListener native;
auto initiated_cb = std::move(listener.initiated_cb);
if (initiated_cb) {
native.initiated_cb =
[cb = std::move(initiated_cb)](const std::string& endpoint_id,
const nearby::sharing::ConnectionInfo&
info) mutable {
Facade::ConnectionInfo translated;
translated.is_incoming_connection = info.is_incoming_connection;
translated.endpoint_info = info.endpoint_info;
translated.peer_name = DecodePeerName(translated.endpoint_info);
cb(endpoint_id, std::move(translated));
};
}
auto accepted_cb = std::move(listener.accepted_cb);
if (accepted_cb) {
native.accepted_cb = [cb = std::move(accepted_cb)](
const std::string& endpoint_id) mutable {
cb(endpoint_id);
};
}
auto rejected_cb = std::move(listener.rejected_cb);
if (rejected_cb) {
native.rejected_cb = [cb = std::move(rejected_cb)](
const std::string& endpoint_id,
nearby::sharing::Status status) mutable {
cb(endpoint_id, ToFacadeStatus(status));
};
}
auto disconnected_cb = std::move(listener.disconnected_cb);
if (disconnected_cb) {
native.disconnected_cb = [cb = std::move(disconnected_cb)](
const std::string& endpoint_id) mutable {
cb(endpoint_id);
};
}
auto bandwidth_changed_cb = std::move(listener.bandwidth_changed_cb);
if (bandwidth_changed_cb) {
native.bandwidth_changed_cb =
[cb = std::move(bandwidth_changed_cb)](const std::string& endpoint_id,
nearby::sharing::Medium medium)
mutable { cb(endpoint_id, ToFacadeMedium(medium)); };
}
return native;
}
NativeService::DiscoveryListener ToNativeDiscoveryListener(
Facade::DiscoveryListener listener) {
NativeService::DiscoveryListener native;
auto endpoint_found_cb = std::move(listener.endpoint_found_cb);
if (endpoint_found_cb) {
native.endpoint_found_cb =
[cb = std::move(endpoint_found_cb)](
const std::string& endpoint_id,
const nearby::sharing::DiscoveredEndpointInfo& info) mutable {
Facade::DiscoveredEndpointInfo translated;
translated.endpoint_info = info.endpoint_info;
translated.service_id = info.service_id;
translated.peer_name = DecodePeerName(translated.endpoint_info);
cb(endpoint_id, std::move(translated));
};
}
auto endpoint_lost_cb = std::move(listener.endpoint_lost_cb);
if (endpoint_lost_cb) {
native.endpoint_lost_cb = [cb = std::move(endpoint_lost_cb)](
const std::string& endpoint_id) mutable {
cb(endpoint_id);
};
}
auto endpoint_distance_changed_cb =
std::move(listener.endpoint_distance_changed_cb);
if (endpoint_distance_changed_cb) {
native.endpoint_distance_changed_cb =
[cb = std::move(endpoint_distance_changed_cb)](
const std::string& endpoint_id,
nearby::sharing::DistanceInfo distance_info) mutable {
cb(endpoint_id, ToFacadeDistance(distance_info));
};
}
return native;
}
NativeService::PayloadListener ToNativePayloadListener(
Facade::PayloadListener listener) {
NativeService::PayloadListener native;
auto payload_cb = std::move(listener.payload_cb);
if (payload_cb) {
native.payload_cb =
[cb = std::move(payload_cb)](absl::string_view endpoint_id,
nearby::sharing::Payload payload) mutable {
Facade::Payload translated;
translated.id = payload.id;
if (payload.content.is_bytes()) {
translated.type = Facade::Payload::Type::kBytes;
translated.bytes = std::move(payload.content.bytes_payload.bytes);
} else if (payload.content.is_file()) {
translated.type = Facade::Payload::Type::kFile;
translated.parent_folder = payload.content.file_payload.parent_folder;
translated.file_path =
payload.content.file_payload.file_path.ToString();
translated.file_name = payload.content.file_payload.file_path.GetFileName().ToString();
}
cb(std::string(endpoint_id), std::move(translated));
};
}
auto progress_cb = std::move(listener.payload_progress_cb);
if (progress_cb) {
native.payload_progress_cb = [cb = std::move(progress_cb)](
absl::string_view endpoint_id,
const nearby::sharing::PayloadTransferUpdate&
update) mutable {
cb(std::string(endpoint_id),
Facade::PayloadTransferUpdate{
update.payload_id,
ToFacadePayloadStatus(update.status),
update.total_bytes,
update.bytes_transferred,
});
};
}
return native;
}
std::unique_ptr<nearby::sharing::Payload> ToNativePayload(Facade::Payload payload) {
const int64_t payload_id = payload.id == 0 ? NextPayloadId() : payload.id;
switch (payload.type) {
case Facade::Payload::Type::kBytes:
return std::make_unique<nearby::sharing::Payload>(
payload_id, std::move(payload.bytes));
case Facade::Payload::Type::kFile:
return std::make_unique<nearby::sharing::Payload>(
payload_id, FilePath(payload.file_path), payload.parent_folder);
case Facade::Payload::Type::kUnknown:
return nullptr;
}
return nullptr;
}
} // namespace
class NearbyConnectionsQtFacade::Impl {
public:
Impl() : service(std::make_unique<linux::NearbyConnectionsServiceLinux>()) {}
std::unique_ptr<NativeService> service;
};
NearbyConnectionsQtFacade::NearbyConnectionsQtFacade()
: impl_(std::make_unique<Impl>()) {}
NearbyConnectionsQtFacade::~NearbyConnectionsQtFacade() = default;
NearbyConnectionsQtFacade::NearbyConnectionsQtFacade(
NearbyConnectionsQtFacade&&) noexcept = default;
NearbyConnectionsQtFacade& NearbyConnectionsQtFacade::operator=(
NearbyConnectionsQtFacade&&) noexcept = default;
void NearbyConnectionsQtFacade::SetBleL2capFlagOverrides(
bool enable_ble_l2cap, bool refactor_ble_l2cap) {
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
nearby::connections::config_package_nearby::nearby_connections_feature::
kEnableBleL2cap,
enable_ble_l2cap);
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
nearby::connections::config_package_nearby::nearby_connections_feature::
kRefactorBleL2cap,
refactor_ble_l2cap);
}
NearbyConnectionsQtFacade::Payload NearbyConnectionsQtFacade::CreateBytesPayload(
std::vector<uint8_t> bytes) const {
Payload payload;
payload.id = NextPayloadId();
payload.type = Payload::Type::kBytes;
payload.bytes = std::move(bytes);
return payload;
}
void NearbyConnectionsQtFacade::StartAdvertising(
const std::string& service_id, const std::vector<uint8_t>& endpoint_info,
const AdvertisingOptions& advertising_options,
ConnectionListener advertising_listener,
std::function<void(Status)> callback) {
impl_->service->StartAdvertising(
service_id, endpoint_info, ToNativeAdvertisingOptions(advertising_options),
ToNativeConnectionListener(std::move(advertising_listener)),
ToNativeStatusCallback(std::move(callback)));
}
void NearbyConnectionsQtFacade::StopAdvertising(
const std::string& service_id, std::function<void(Status)> callback) {
impl_->service->StopAdvertising(service_id,
ToNativeStatusCallback(std::move(callback)));
}
void NearbyConnectionsQtFacade::StartDiscovery(
const std::string& service_id, const DiscoveryOptions& discovery_options,
DiscoveryListener discovery_listener, std::function<void(Status)> callback) {
impl_->service->StartDiscovery(
service_id, ToNativeDiscoveryOptions(discovery_options),
ToNativeDiscoveryListener(std::move(discovery_listener)),
ToNativeStatusCallback(std::move(callback)));
}
void NearbyConnectionsQtFacade::StopDiscovery(const std::string& service_id,
std::function<void(Status)> callback) {
impl_->service->StopDiscovery(service_id,
ToNativeStatusCallback(std::move(callback)));
}
void NearbyConnectionsQtFacade::RequestConnection(
const std::string& service_id, const std::vector<uint8_t>& endpoint_info,
const std::string& endpoint_id, const ConnectionOptions& connection_options,
ConnectionListener connection_listener, std::function<void(Status)> callback) {
impl_->service->RequestConnection(
service_id, endpoint_info, endpoint_id,
ToNativeConnectionOptions(connection_options),
ToNativeConnectionListener(std::move(connection_listener)),
ToNativeStatusCallback(std::move(callback)));
}
void NearbyConnectionsQtFacade::DisconnectFromEndpoint(
const std::string& service_id, const std::string& endpoint_id,
std::function<void(Status)> callback) {
impl_->service->DisconnectFromEndpoint(
service_id, endpoint_id, ToNativeStatusCallback(std::move(callback)));
}
void NearbyConnectionsQtFacade::SendPayload(
const std::string& service_id, const std::vector<std::string>& endpoint_ids,
Payload payload, std::function<void(Status)> callback) {
auto native_payload = ToNativePayload(std::move(payload));
if (!native_payload) {
if (callback) {
callback(Status::kError);
}
return;
}
impl_->service->SendPayload(service_id, endpoint_ids,
std::move(native_payload),
ToNativeStatusCallback(std::move(callback)));
}
void NearbyConnectionsQtFacade::InitiateBandwidthUpgrade(
const std::string& service_id, const std::string& endpoint_id,
std::function<void(Status)> callback) {
impl_->service->InitiateBandwidthUpgrade(
service_id, endpoint_id, ToNativeStatusCallback(std::move(callback)));
}
void NearbyConnectionsQtFacade::AcceptConnection(
const std::string& service_id, const std::string& endpoint_id,
PayloadListener payload_listener, std::function<void(Status)> callback) {
impl_->service->AcceptConnection(
service_id, endpoint_id, ToNativePayloadListener(std::move(payload_listener)),
ToNativeStatusCallback(std::move(callback)));
}
void NearbyConnectionsQtFacade::StopAllEndpoints(
std::function<void(Status)> callback) {
impl_->service->StopAllEndpoints(ToNativeStatusCallback(std::move(callback)));
}
} // namespace nearby::sharing
@@ -1,228 +0,0 @@
// Copyright 2026
//
// Thin C++ facade around NearbyConnectionsServiceLinux for UI clients that
// should not include internal Nearby/Abseil/Protobuf headers.
#ifndef SHARING_LINUX_NEARBY_CONNECTIONS_QT_FACADE_H_
#define SHARING_LINUX_NEARBY_CONNECTIONS_QT_FACADE_H_
#include <stdint.h>
#include <functional>
#include <memory>
#include <string>
#include <vector>
// Some toolchains define `linux` as a macro (e.g. `#define linux 1`), which
// breaks namespace tokens like `nearby::sharing::linux`.
#ifdef linux
#undef linux
#endif
namespace nearby {
namespace sharing {
class __attribute__((visibility("default"))) NearbyConnectionsQtFacade {
public:
enum class Status {
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,
kNextValue = 19,
};
enum class PayloadStatus {
kSuccess,
kFailure,
kInProgress,
kCanceled,
};
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 Strategy {
kP2pCluster = 0,
kP2pStar = 1,
kP2pPointToPoint = 2,
};
struct ConnectionInfo {
bool is_incoming_connection = false;
std::vector<uint8_t> endpoint_info;
std::string peer_name;
};
struct DiscoveredEndpointInfo {
std::vector<uint8_t> endpoint_info;
std::string service_id;
std::string peer_name;
};
struct PayloadTransferUpdate {
int64_t payload_id = 0;
PayloadStatus status = PayloadStatus::kFailure;
uint64_t total_bytes = 0;
uint64_t bytes_transferred = 0;
};
struct Payload {
enum class Type {
kUnknown = 0,
kBytes = 1,
kFile = 3,
};
int64_t id = 0;
Type type = Type::kUnknown;
std::vector<uint8_t> bytes;
std::string file_path;
std::string file_name;
std::string parent_folder;
};
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;
};
struct DiscoveryOptions {
Strategy strategy = Strategy::kP2pCluster;
MediumSelection allowed_mediums;
};
struct ConnectionOptions {
MediumSelection allowed_mediums;
bool non_disruptive_hotspot_mode = false;
};
struct ConnectionListener {
std::function<void(const std::string &, const ConnectionInfo &)>
initiated_cb;
std::function<void(const std::string &)> accepted_cb;
std::function<void(const std::string &, Status)> rejected_cb;
std::function<void(const std::string &)> disconnected_cb;
std::function<void(const std::string &, Medium)> bandwidth_changed_cb;
};
struct DiscoveryListener {
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;
};
struct PayloadListener {
std::function<void(const std::string &, Payload)> payload_cb;
std::function<void(const std::string &, const PayloadTransferUpdate &)>
payload_progress_cb;
};
NearbyConnectionsQtFacade();
~NearbyConnectionsQtFacade();
NearbyConnectionsQtFacade(const NearbyConnectionsQtFacade &) = delete;
NearbyConnectionsQtFacade &
operator=(const NearbyConnectionsQtFacade &) = delete;
NearbyConnectionsQtFacade(NearbyConnectionsQtFacade &&) noexcept;
NearbyConnectionsQtFacade &operator=(NearbyConnectionsQtFacade &&) noexcept;
// Sets global Nearby flag overrides for BLE L2CAP.
static void SetBleL2capFlagOverrides(bool enable_ble_l2cap,
bool refactor_ble_l2cap);
Payload CreateBytesPayload(std::vector<uint8_t> bytes) const;
void StartAdvertising(const std::string &service_id,
const std::vector<uint8_t> &endpoint_info,
const AdvertisingOptions &advertising_options,
ConnectionListener advertising_listener,
std::function<void(Status)> callback);
void StopAdvertising(const std::string &service_id,
std::function<void(Status)> callback);
void StartDiscovery(const std::string &service_id,
const DiscoveryOptions &discovery_options,
DiscoveryListener discovery_listener,
std::function<void(Status)> callback);
void StopDiscovery(const std::string &service_id,
std::function<void(Status)> callback);
void RequestConnection(const std::string &service_id,
const std::vector<uint8_t> &endpoint_info,
const std::string &endpoint_id,
const ConnectionOptions &connection_options,
ConnectionListener connection_listener,
std::function<void(Status)> callback);
void DisconnectFromEndpoint(const std::string &service_id,
const std::string &endpoint_id,
std::function<void(Status)> callback);
void SendPayload(const std::string &service_id,
const std::vector<std::string> &endpoint_ids,
Payload payload, std::function<void(Status)> callback);
void InitiateBandwidthUpgrade(const std::string &service_id,
const std::string &endpoint_id,
std::function<void(Status)> callback);
void AcceptConnection(const std::string &service_id,
const std::string &endpoint_id,
PayloadListener payload_listener,
std::function<void(Status)> callback);
void StopAllEndpoints(std::function<void(Status)> callback);
private:
class Impl;
std::unique_ptr<Impl> impl_;
};
} // namespace sharing
} // namespace nearby
#endif // SHARING_LINUX_NEARBY_CONNECTIONS_QT_FACADE_H_
@@ -1,445 +0,0 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "sharing/linux/nearby_connections_service_linux.h"
#include <stdint.h>
#include <algorithm>
#include <cstdlib>
#include <functional>
#include <memory>
#include <string>
#include <utility>
#include <vector>
#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/listeners.h"
#include "connections/payload.h"
#include "connections/payload_type.h"
#include "connections/status.h"
#include "connections/strategy.h"
#include "internal/base/file_path.h"
#include "internal/platform/byte_array.h"
#include "internal/platform/file.h"
#include "internal/platform/logging.h"
#include "internal/platform/mac_address.h"
namespace nearby {
namespace sharing::linux {
namespace {
using ::nearby::connections::ConnectionRequestInfo;
using ::nearby::connections::ConnectionResponseInfo;
using ::nearby::connections::PayloadProgressInfo;
using ::nearby::connections::PayloadType;
using NcAdvertisingOptions = ::nearby::connections::AdvertisingOptions;
using NcConnectionOptions = ::nearby::connections::ConnectionOptions;
using NcDiscoveryListener = ::nearby::connections::DiscoveryListener;
using NcDiscoveryOptions = ::nearby::connections::DiscoveryOptions;
using NcDistanceInfo = ::nearby::connections::DistanceInfo;
using NcMedium = ::nearby::connections::Medium;
using NcPayload = ::nearby::connections::Payload;
using NcPayloadListener = ::nearby::connections::PayloadListener;
using NcResultCallback = ::nearby::connections::ResultCallback;
using NcStatus = ::nearby::connections::Status;
using NcStrategy = ::nearby::connections::Strategy;
Status ConvertStatus(NcStatus status) {
return static_cast<Status>(status.value);
}
NcResultCallback MakeResultCallback(std::function<void(Status status)> callback) {
return [callback = std::move(callback)](NcStatus status) {
callback(ConvertStatus(status));
};
}
Payload ConvertPayload(NcPayload payload) {
switch (payload.GetType()) {
case PayloadType::kBytes: {
const ByteArray& bytes = payload.AsBytes();
std::string data = std::string(bytes);
return Payload(payload.GetId(),
std::vector<uint8_t>(data.begin(), data.end()));
}
case PayloadType::kFile: {
std::string file_path = payload.AsFile()->GetFilePath();
std::string parent_folder = payload.GetParentFolder();
VLOG(1) << __func__ << ": Payload file_path=" << file_path
<< ", parent_folder=" << parent_folder;
return Payload(payload.GetId(), FilePath(file_path), parent_folder);
}
default:
return Payload();
}
}
NcPayload ConvertToNcPayload(Payload payload) {
switch (payload.content.type) {
case PayloadContent::Type::kFile: {
std::string file_path = payload.content.file_payload.file_path.ToString();
std::string file_name =
payload.content.file_payload.file_path.GetFileName().ToString();
std::string parent_folder = payload.content.file_payload.parent_folder;
std::replace(parent_folder.begin(), parent_folder.end(), '\\', '/');
VLOG(1) << __func__ << ": NC Payload file_path=" << file_path
<< ", parent_folder=" << parent_folder;
nearby::InputFile input_file(file_path);
return NcPayload(payload.id, parent_folder, file_name,
std::move(input_file));
}
case PayloadContent::Type::kBytes: {
std::vector<uint8_t> bytes = payload.content.bytes_payload.bytes;
return NcPayload(payload.id,
ByteArray(std::string(bytes.begin(), bytes.end())));
}
default:
return NcPayload();
}
}
NcStrategy ConvertStrategy(Strategy strategy) {
switch (strategy) {
case Strategy::kP2pCluster:
return NcStrategy::kP2pCluster;
case Strategy::kP2pPointToPoint:
return NcStrategy::kP2pPointToPoint;
case Strategy::kP2pStar:
return NcStrategy::kP2pStar;
}
return NcStrategy::kP2pPointToPoint;
}
void SetUpgradeMediumEnv(const nearby::sharing::MediumSelection& mediums) {
setenv("NEARBY_ALLOW_UPGRADE_BLUETOOTH", mediums.bluetooth ? "1" : "0", 1);
setenv("NEARBY_ALLOW_UPGRADE_BLE", mediums.ble ? "1" : "0", 1);
setenv("NEARBY_ALLOW_UPGRADE_WEB_RTC", mediums.web_rtc ? "1" : "0", 1);
setenv("NEARBY_ALLOW_UPGRADE_WIFI_LAN", mediums.wifi_lan ? "1" : "0", 1);
setenv("NEARBY_ALLOW_UPGRADE_WIFI_HOTSPOT",
mediums.wifi_hotspot ? "1" : "0", 1);
setenv("NEARBY_ALLOW_UPGRADE_WIFI_DIRECT", "0", 1);
setenv("NEARBY_ALLOW_UPGRADE_AWDL", "0", 1);
}
ConnectionInfo ConvertConnectionInfo(const ConnectionResponseInfo& info) {
ConnectionInfo connection_info;
connection_info.authentication_token = info.authentication_token;
std::string remote_endpoint_info = std::string(info.remote_endpoint_info);
connection_info.endpoint_info = std::vector<uint8_t>(
remote_endpoint_info.begin(), remote_endpoint_info.end());
connection_info.is_incoming_connection = info.is_incoming_connection;
std::string raw_authentication_token =
std::string(info.raw_authentication_token);
connection_info.raw_authentication_token = std::vector<uint8_t>(
raw_authentication_token.begin(), raw_authentication_token.end());
return connection_info;
}
} // namespace
NearbyConnectionsServiceLinux::NearbyConnectionsServiceLinux()
: core_(&router_) {}
NearbyConnectionsServiceLinux::NearbyConnectionsServiceLinux(
nearby::analytics::EventLogger* event_logger)
: core_(event_logger, &router_) {}
NearbyConnectionsServiceLinux::~NearbyConnectionsServiceLinux() = default;
void NearbyConnectionsServiceLinux::StartAdvertising(
absl::string_view service_id, const std::vector<uint8_t>& endpoint_info,
const AdvertisingOptions& advertising_options,
ConnectionListener advertising_listener,
std::function<void(Status status)> callback) {
advertising_listener_ = std::move(advertising_listener);
SetUpgradeMediumEnv(advertising_options.allowed_mediums);
NcAdvertisingOptions options{};
options.strategy = ConvertStrategy(advertising_options.strategy);
options.allowed.SetAll(false);
options.allowed.ble = advertising_options.allowed_mediums.ble;
options.allowed.bluetooth = advertising_options.allowed_mediums.bluetooth;
options.allowed.web_rtc = advertising_options.allowed_mediums.web_rtc;
options.allowed.wifi_lan = advertising_options.allowed_mediums.wifi_lan;
options.allowed.wifi_hotspot = advertising_options.allowed_mediums.wifi_hotspot;
options.auto_upgrade_bandwidth = advertising_options.auto_upgrade_bandwidth;
options.enforce_topology_constraints =
advertising_options.enforce_topology_constraints;
options.enable_bluetooth_listening =
advertising_options.enable_bluetooth_listening;
options.enable_webrtc_listening = advertising_options.enable_webrtc_listening;
options.use_stable_endpoint_id = advertising_options.use_stable_endpoint_id;
options.force_new_endpoint_id = false;
options.fast_advertisement_service_uuid =
advertising_options.fast_advertisement_service_uuid.uuid;
ConnectionRequestInfo request_info;
request_info.endpoint_info =
ByteArray(std::string(endpoint_info.begin(), endpoint_info.end()));
request_info.listener.initiated_cb = [this](const std::string& endpoint_id,
const ConnectionResponseInfo& info) {
advertising_listener_.initiated_cb(endpoint_id, ConvertConnectionInfo(info));
};
request_info.listener.accepted_cb = [this](const std::string& endpoint_id) {
advertising_listener_.accepted_cb(endpoint_id);
};
request_info.listener.rejected_cb =
[this](const std::string& endpoint_id, NcStatus status) {
advertising_listener_.rejected_cb(endpoint_id, ConvertStatus(status));
};
request_info.listener.disconnected_cb =
[this](const std::string& endpoint_id) {
payload_listeners_.erase(endpoint_id);
advertising_listener_.disconnected_cb(endpoint_id);
};
request_info.listener.bandwidth_changed_cb =
[this](const std::string& endpoint_id, NcMedium medium) {
advertising_listener_.bandwidth_changed_cb(endpoint_id,
static_cast<Medium>(medium));
};
core_.StartAdvertising(service_id, options, std::move(request_info),
MakeResultCallback(std::move(callback)));
}
void NearbyConnectionsServiceLinux::StopAdvertising(
absl::string_view service_id, std::function<void(Status status)> callback) {
static_cast<void>(service_id);
core_.StopAdvertising(MakeResultCallback(std::move(callback)));
}
void NearbyConnectionsServiceLinux::StartDiscovery(
absl::string_view service_id, const DiscoveryOptions& discovery_options,
DiscoveryListener discovery_listener,
std::function<void(Status status)> callback) {
discovery_listener_ = std::move(discovery_listener);
SetUpgradeMediumEnv(discovery_options.allowed_mediums);
NcDiscoveryOptions options{};
options.strategy = ConvertStrategy(discovery_options.strategy);
options.allowed.SetAll(false);
options.allowed.ble = discovery_options.allowed_mediums.ble;
options.allowed.bluetooth = discovery_options.allowed_mediums.bluetooth;
options.allowed.web_rtc = discovery_options.allowed_mediums.web_rtc;
options.allowed.wifi_lan = discovery_options.allowed_mediums.wifi_lan;
options.allowed.wifi_hotspot = discovery_options.allowed_mediums.wifi_hotspot;
if (discovery_options.fast_advertisement_service_uuid.has_value()) {
options.fast_advertisement_service_uuid =
(*discovery_options.fast_advertisement_service_uuid).uuid;
}
options.is_out_of_band_connection =
discovery_options.is_out_of_band_connection;
if (discovery_options.alternate_service_uuid.has_value()) {
options.ble_options.alternate_uuid =
discovery_options.alternate_service_uuid;
}
NcDiscoveryListener listener;
listener.endpoint_found_cb = [this](const std::string& endpoint_id,
const ByteArray& endpoint_info,
const std::string& discovered_service_id) {
std::string endpoint_info_data = std::string(endpoint_info);
discovery_listener_.endpoint_found_cb(
endpoint_id,
DiscoveredEndpointInfo(std::vector<uint8_t>(endpoint_info_data.begin(),
endpoint_info_data.end()),
discovered_service_id));
};
listener.endpoint_lost_cb = [this](const std::string& endpoint_id) {
discovery_listener_.endpoint_lost_cb(endpoint_id);
};
listener.endpoint_distance_changed_cb = [this](const std::string& endpoint_id,
NcDistanceInfo distance_info) {
discovery_listener_.endpoint_distance_changed_cb(
endpoint_id, static_cast<DistanceInfo>(distance_info));
};
core_.StartDiscovery(service_id, options, std::move(listener),
MakeResultCallback(std::move(callback)));
}
void NearbyConnectionsServiceLinux::StopDiscovery(
absl::string_view service_id, std::function<void(Status status)> callback) {
static_cast<void>(service_id);
core_.StopDiscovery(MakeResultCallback(std::move(callback)));
}
void NearbyConnectionsServiceLinux::RequestConnection(
absl::string_view service_id, const std::vector<uint8_t>& endpoint_info,
absl::string_view endpoint_id, const ConnectionOptions& connection_options,
ConnectionListener connection_listener,
std::function<void(Status status)> callback) {
static_cast<void>(service_id);
connection_listener_ = std::move(connection_listener);
SetUpgradeMediumEnv(connection_options.allowed_mediums);
NcConnectionOptions options{};
options.allowed.SetAll(false);
options.allowed.ble = connection_options.allowed_mediums.ble;
options.allowed.bluetooth = connection_options.allowed_mediums.bluetooth;
options.allowed.web_rtc = connection_options.allowed_mediums.web_rtc;
options.allowed.wifi_lan = connection_options.allowed_mediums.wifi_lan;
options.allowed.wifi_hotspot = connection_options.allowed_mediums.wifi_hotspot;
if (connection_options.keep_alive_interval.has_value()) {
options.keep_alive_interval_millis =
*connection_options.keep_alive_interval / absl::Milliseconds(1);
}
if (connection_options.keep_alive_timeout.has_value()) {
options.keep_alive_timeout_millis =
*connection_options.keep_alive_timeout / absl::Milliseconds(1);
}
if (connection_options.remote_bluetooth_mac_address.has_value()) {
MacAddress mac_address;
MacAddress::FromBytes(
absl::MakeConstSpan(*connection_options.remote_bluetooth_mac_address),
mac_address);
options.remote_bluetooth_mac_address = mac_address;
}
options.non_disruptive_hotspot_mode =
connection_options.non_disruptive_hotspot_mode;
ConnectionRequestInfo request_info;
request_info.endpoint_info =
ByteArray(std::string(endpoint_info.begin(), endpoint_info.end()));
request_info.listener.initiated_cb = [this](const std::string& endpoint_id,
const ConnectionResponseInfo& info) {
connection_listener_.initiated_cb(endpoint_id, ConvertConnectionInfo(info));
};
request_info.listener.accepted_cb = [this](const std::string& endpoint_id) {
connection_listener_.accepted_cb(endpoint_id);
};
request_info.listener.rejected_cb =
[this](const std::string& endpoint_id, NcStatus status) {
connection_listener_.rejected_cb(endpoint_id, ConvertStatus(status));
};
request_info.listener.disconnected_cb =
[this](const std::string& endpoint_id) {
payload_listeners_.erase(endpoint_id);
connection_listener_.disconnected_cb(endpoint_id);
};
request_info.listener.bandwidth_changed_cb =
[this](const std::string& endpoint_id, NcMedium medium) {
connection_listener_.bandwidth_changed_cb(endpoint_id,
static_cast<Medium>(medium));
};
core_.RequestConnection(endpoint_id, std::move(request_info), options,
MakeResultCallback(std::move(callback)));
}
void NearbyConnectionsServiceLinux::DisconnectFromEndpoint(
absl::string_view service_id, absl::string_view endpoint_id,
std::function<void(Status status)> callback) {
static_cast<void>(service_id);
payload_listeners_.erase(std::string(endpoint_id));
core_.DisconnectFromEndpoint(endpoint_id,
MakeResultCallback(std::move(callback)));
}
void NearbyConnectionsServiceLinux::SendPayload(
absl::string_view service_id, absl::Span<const std::string> endpoint_ids,
std::unique_ptr<Payload> payload,
std::function<void(Status status)> callback) {
static_cast<void>(service_id);
core_.SendPayload(endpoint_ids, ConvertToNcPayload(*payload),
MakeResultCallback(std::move(callback)));
}
void NearbyConnectionsServiceLinux::CancelPayload(
absl::string_view service_id, int64_t payload_id,
std::function<void(Status status)> callback) {
static_cast<void>(service_id);
core_.CancelPayload(payload_id, MakeResultCallback(std::move(callback)));
}
void NearbyConnectionsServiceLinux::InitiateBandwidthUpgrade(
absl::string_view service_id, absl::string_view endpoint_id,
std::function<void(Status status)> callback) {
static_cast<void>(service_id);
core_.InitiateBandwidthUpgrade(endpoint_id,
MakeResultCallback(std::move(callback)));
}
void NearbyConnectionsServiceLinux::AcceptConnection(
absl::string_view service_id, absl::string_view endpoint_id,
PayloadListener payload_listener,
std::function<void(Status status)> callback) {
static_cast<void>(service_id);
payload_listeners_[std::string(endpoint_id)] = std::move(payload_listener);
NcPayloadListener service_payload_listener{
.payload_cb =
[this](absl::string_view endpoint_id, NcPayload payload) {
auto it = payload_listeners_.find(std::string(endpoint_id));
if (it == payload_listeners_.end()) {
return;
}
VLOG(1) << "payload callback id=" << payload.GetId();
switch (payload.GetType()) {
case PayloadType::kBytes:
case PayloadType::kFile:
it->second.payload_cb(endpoint_id,
ConvertPayload(std::move(payload)));
break;
default:
break;
}
},
.payload_progress_cb =
[this](absl::string_view endpoint_id, const PayloadProgressInfo& info) {
auto it = payload_listeners_.find(std::string(endpoint_id));
if (it == payload_listeners_.end()) {
return;
}
PayloadTransferUpdate transfer_update;
transfer_update.bytes_transferred = info.bytes_transferred;
transfer_update.payload_id = info.payload_id;
transfer_update.status = static_cast<PayloadStatus>(info.status);
transfer_update.total_bytes = info.total_bytes;
VLOG(1) << "payload transfer update id=" << info.payload_id;
it->second.payload_progress_cb(endpoint_id, transfer_update);
}};
core_.AcceptConnection(endpoint_id, std::move(service_payload_listener),
MakeResultCallback(std::move(callback)));
}
void NearbyConnectionsServiceLinux::StopAllEndpoints(
std::function<void(Status status)> callback) {
payload_listeners_.clear();
core_.StopAllEndpoints(MakeResultCallback(std::move(callback)));
}
void NearbyConnectionsServiceLinux::SetCustomSavePath(
absl::string_view path, std::function<void(Status status)> callback) {
core_.SetCustomSavePath(path, MakeResultCallback(std::move(callback)));
}
std::string NearbyConnectionsServiceLinux::Dump() const {
// NearbyConnectionsService requires const Dump(), but Core::Dump() is
// non-const in this codebase.
return const_cast<connections::Core&>(core_).Dump();
}
} // namespace sharing::linux
} // namespace nearby
@@ -1,114 +0,0 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_SHARING_LINUX_NEARBY_CONNECTIONS_SERVICE_LINUX_H_
#define THIRD_PARTY_NEARBY_SHARING_LINUX_NEARBY_CONNECTIONS_SERVICE_LINUX_H_
#include <stdint.h>
#include <functional>
#include <memory>
#include <string>
#include <vector>
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "connections/core.h"
#include "connections/implementation/service_controller_router.h"
#include "sharing/nearby_connections_service.h"
#include "sharing/nearby_connections_types.h"
namespace nearby {
namespace analytics {
class EventLogger;
} // namespace analytics
namespace sharing::linux {
class NearbyConnectionsServiceLinux : public NearbyConnectionsService {
public:
NearbyConnectionsServiceLinux();
explicit NearbyConnectionsServiceLinux(
nearby::analytics::EventLogger* event_logger);
~NearbyConnectionsServiceLinux() override;
NearbyConnectionsServiceLinux(const NearbyConnectionsServiceLinux&) = delete;
NearbyConnectionsServiceLinux& operator=(
const NearbyConnectionsServiceLinux&) = delete;
NearbyConnectionsServiceLinux(NearbyConnectionsServiceLinux&&) = delete;
NearbyConnectionsServiceLinux& operator=(NearbyConnectionsServiceLinux&&) =
delete;
void StartAdvertising(absl::string_view service_id,
const std::vector<uint8_t>& endpoint_info,
const AdvertisingOptions& advertising_options,
ConnectionListener advertising_listener,
std::function<void(Status status)> callback) override;
void StopAdvertising(absl::string_view service_id,
std::function<void(Status status)> callback) override;
void StartDiscovery(absl::string_view service_id,
const DiscoveryOptions& discovery_options,
DiscoveryListener discovery_listener,
std::function<void(Status status)> callback) override;
void StopDiscovery(absl::string_view service_id,
std::function<void(Status status)> callback) override;
void RequestConnection(absl::string_view service_id,
const std::vector<uint8_t>& endpoint_info,
absl::string_view endpoint_id,
const ConnectionOptions& connection_options,
ConnectionListener connection_listener,
std::function<void(Status status)> callback) override;
void DisconnectFromEndpoint(
absl::string_view service_id, absl::string_view endpoint_id,
std::function<void(Status status)> callback) override;
void SendPayload(absl::string_view service_id,
absl::Span<const std::string> endpoint_ids,
std::unique_ptr<Payload> payload,
std::function<void(Status status)> callback) override;
void CancelPayload(absl::string_view service_id, int64_t payload_id,
std::function<void(Status status)> callback) override;
void InitiateBandwidthUpgrade(
absl::string_view service_id, absl::string_view endpoint_id,
std::function<void(Status status)> callback) override;
void AcceptConnection(absl::string_view service_id,
absl::string_view endpoint_id,
PayloadListener payload_listener,
std::function<void(Status status)> callback) override;
void StopAllEndpoints(std::function<void(Status status)> callback) override;
void SetCustomSavePath(absl::string_view path,
std::function<void(Status status)> callback) override;
std::string Dump() const override;
private:
connections::ServiceControllerRouter router_;
connections::Core core_;
ConnectionListener advertising_listener_;
DiscoveryListener discovery_listener_;
ConnectionListener connection_listener_;
absl::flat_hash_map<std::string, PayloadListener> payload_listeners_;
};
} // namespace sharing::linux
} // namespace nearby
#endif // THIRD_PARTY_NEARBY_SHARING_LINUX_NEARBY_CONNECTIONS_SERVICE_LINUX_H_
+196 -23
View File
@@ -3,15 +3,27 @@
#include <limits>
#include <mutex>
#include <optional>
#include <string>
#include <utility>
#include <openssl/bn.h>
#include <openssl/ec.h>
#include <openssl/evp.h>
#include "absl/strings/escaping.h"
#include "absl/time/time.h"
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
#include "internal/base/file_path.h"
#include "internal/base/files.h"
#include "internal/crypto_cros/ec_private_key.h"
#include "internal/flags/nearby_flags.h"
#include "sharing/analytics/analytics_recorder.h"
#include "sharing/attachment_container.h"
#include "sharing/file_attachment.h"
#include "sharing/linux/nearby_sharing_service_linux.h"
#include "sharing/linux/platform/linux_sharing_platform.h"
#include "sharing/local_device_data/nearby_share_local_device_data_manager.h"
#include "sharing/nearby_sharing_service_factory.h"
#include "sharing/proto/enums.pb.h"
#include "sharing/share_target_discovered_callback.h"
#include "sharing/transfer_metadata.h"
#include "sharing/transfer_update_callback.h"
@@ -20,7 +32,7 @@ namespace nearby::sharing::linux {
namespace {
using NativeService = nearby::sharing::linux::NearbySharingServiceLinux;
using NativeService = nearby::sharing::NearbySharingService;
void EnableBleL2capDefaults() {
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
@@ -113,14 +125,89 @@ NearbySharingApi::TextAttachmentType ToFacadeTextAttachmentType(
return FacadeType::kUnknown;
}
std::string GenerateQrCodeUrl() {
auto ec_key = nearby::crypto::ECPrivateKey::Create();
if (!ec_key) {
return {};
}
const EC_KEY* raw_ec_key = EVP_PKEY_get0_EC_KEY(ec_key->key());
if (!raw_ec_key) {
return {};
}
const EC_GROUP* group = EC_KEY_get0_group(raw_ec_key);
const EC_POINT* public_key = EC_KEY_get0_public_key(raw_ec_key);
if (!group || !public_key) {
return {};
}
BIGNUM* x = BN_new();
BIGNUM* y = BN_new();
if (!x || !y) {
BN_free(x);
BN_free(y);
return {};
}
if (!EC_POINT_get_affine_coordinates_GFp(group, public_key, x, y, nullptr)) {
BN_free(x);
BN_free(y);
return {};
}
std::vector<uint8_t> x_bytes(32, 0);
const int x_len = BN_num_bytes(x);
if (x_len > static_cast<int>(x_bytes.size())) {
BN_free(x);
BN_free(y);
return {};
}
BN_bn2bin(x, x_bytes.data() + (x_bytes.size() - x_len));
const uint8_t prefix = BN_is_odd(y) ? 0x03 : 0x02;
BN_free(x);
BN_free(y);
std::vector<uint8_t> key_data;
key_data.reserve(35);
key_data.push_back(0x00);
key_data.push_back(0x00);
key_data.push_back(prefix);
key_data.insert(key_data.end(), x_bytes.begin(), x_bytes.end());
std::string encoded;
absl::WebSafeBase64Escape(
std::string(reinterpret_cast<const char*>(key_data.data()),
key_data.size()),
&encoded);
return "https://quickshare.google/qrcode#key=" + encoded;
}
} // namespace
class NearbySharingApi::Impl : public nearby::sharing::ShareTargetDiscoveredCallback,
public nearby::sharing::TransferUpdateCallback {
public:
Impl() : service() {}
Impl()
: analytics_recorder(0, nullptr),
platform(),
service(NearbySharingServiceFactory::GetInstance()->CreateSharingService(
platform, &analytics_recorder, /*event_logger=*/nullptr,
/*supports_file_sync=*/false)) {}
explicit Impl(std::string device_name_override)
: service(std::move(device_name_override)) {}
: analytics_recorder(0, nullptr),
device_name_override(device_name_override),
platform(device_name_override),
service(NearbySharingServiceFactory::GetInstance()->CreateSharingService(
platform, &analytics_recorder, /*event_logger=*/nullptr,
/*supports_file_sync=*/false)) {
if (service != nullptr && !device_name_override.empty() &&
service->GetLocalDeviceDataManager() != nullptr) {
service->GetLocalDeviceDataManager()->SetDeviceName(device_name_override);
}
}
void OnShareTargetDiscovered(const nearby::sharing::ShareTarget& share_target)
override {
@@ -214,9 +301,13 @@ class NearbySharingApi::Impl : public nearby::sharing::ShareTargetDiscoveredCall
return info;
}
NativeService service;
nearby::sharing::analytics::AnalyticsRecorder analytics_recorder;
std::string device_name_override;
LinuxSharingPlatform platform;
NativeService* service = nullptr;
bool send_mode_started = false;
bool receive_mode_started = false;
std::string qr_code_url;
std::mutex listener_mutex;
NearbySharingApi::Listener listener;
};
@@ -244,13 +335,19 @@ void NearbySharingApi::SetListener(Listener listener) {
}
void NearbySharingApi::StartSendMode(std::function<void(StatusCode)> callback) {
if (impl_->service == nullptr) {
if (callback) {
callback(StatusCode::kError);
}
return;
}
if (impl_->send_mode_started) {
if (callback) {
callback(StatusCode::kOk);
}
return;
}
impl_->service.RegisterSendSurface(
impl_->service->RegisterSendSurface(
impl_.get(), impl_.get(),
nearby::sharing::NearbySharingService::SendSurfaceState::kForeground,
nearby::sharing::Advertisement::BlockedVendorId::kNone,
@@ -267,13 +364,19 @@ void NearbySharingApi::StartSendMode(std::function<void(StatusCode)> callback) {
}
void NearbySharingApi::StopSendMode(std::function<void(StatusCode)> callback) {
if (impl_->service == nullptr) {
if (callback) {
callback(StatusCode::kError);
}
return;
}
if (!impl_->send_mode_started) {
if (callback) {
callback(StatusCode::kStatusAlreadyStopped);
}
return;
}
impl_->service.UnregisterSendSurface(
impl_->service->UnregisterSendSurface(
impl_.get(),
[this, cb = std::move(callback)](
nearby::sharing::NearbySharingService::StatusCodes status) mutable {
@@ -287,35 +390,62 @@ void NearbySharingApi::StopSendMode(std::function<void(StatusCode)> callback) {
}
void NearbySharingApi::StartReceiveMode(std::function<void(StatusCode)> callback) {
if (impl_->service == nullptr) {
if (callback) {
callback(StatusCode::kError);
}
return;
}
if (impl_->receive_mode_started) {
if (callback) {
callback(StatusCode::kOk);
}
return;
}
impl_->service.RegisterReceiveSurface(
impl_.get(),
nearby::sharing::NearbySharingService::ReceiveSurfaceState::kForeground,
nearby::sharing::Advertisement::BlockedVendorId::kNone,
impl_->service->SetVisibility(
nearby::sharing::proto::DeviceVisibility::DEVICE_VISIBILITY_EVERYONE,
absl::Minutes(10),
[this, cb = std::move(callback)](
nearby::sharing::NearbySharingService::StatusCodes status) mutable {
if (status == nearby::sharing::NearbySharingService::StatusCodes::kOk) {
impl_->receive_mode_started = true;
}
if (cb) {
cb(ToFacadeStatus(status));
if (status != nearby::sharing::NearbySharingService::StatusCodes::kOk) {
if (cb) {
cb(ToFacadeStatus(status));
}
return;
}
impl_->service->RegisterReceiveSurface(
impl_.get(),
nearby::sharing::NearbySharingService::ReceiveSurfaceState::
kForeground,
nearby::sharing::Advertisement::BlockedVendorId::kNone,
[this, cb = std::move(cb)](
nearby::sharing::NearbySharingService::StatusCodes status)
mutable {
if (status ==
nearby::sharing::NearbySharingService::StatusCodes::kOk) {
impl_->receive_mode_started = true;
}
if (cb) {
cb(ToFacadeStatus(status));
}
});
});
}
void NearbySharingApi::StopReceiveMode(std::function<void(StatusCode)> callback) {
if (impl_->service == nullptr) {
if (callback) {
callback(StatusCode::kError);
}
return;
}
if (!impl_->receive_mode_started) {
if (callback) {
callback(StatusCode::kStatusAlreadyStopped);
}
return;
}
impl_->service.UnregisterReceiveSurface(
impl_->service->UnregisterReceiveSurface(
impl_.get(),
[this, cb = std::move(callback)](
nearby::sharing::NearbySharingService::StatusCodes status) mutable {
@@ -331,6 +461,12 @@ void NearbySharingApi::StopReceiveMode(std::function<void(StatusCode)> callback)
void NearbySharingApi::SendFile(int64_t share_target_id,
const std::string& file_path,
std::function<void(StatusCode)> callback) {
if (impl_->service == nullptr) {
if (callback) {
callback(StatusCode::kError);
}
return;
}
if (file_path.empty()) {
if (callback) {
callback(StatusCode::kInvalidArgument);
@@ -362,7 +498,7 @@ void NearbySharingApi::SendFile(int64_t share_target_id,
return;
}
impl_->service.SendAttachments(
impl_->service->SendAttachments(
share_target_id, std::move(attachments),
[cb = std::move(callback)](
nearby::sharing::NearbySharingService::StatusCodes status) mutable {
@@ -374,7 +510,13 @@ void NearbySharingApi::SendFile(int64_t share_target_id,
void NearbySharingApi::Accept(int64_t share_target_id,
std::function<void(StatusCode)> callback) {
impl_->service.Accept(
if (impl_->service == nullptr) {
if (callback) {
callback(StatusCode::kError);
}
return;
}
impl_->service->Accept(
share_target_id,
[cb = std::move(callback)](
nearby::sharing::NearbySharingService::StatusCodes status) mutable {
@@ -386,7 +528,13 @@ void NearbySharingApi::Accept(int64_t share_target_id,
void NearbySharingApi::Reject(int64_t share_target_id,
std::function<void(StatusCode)> callback) {
impl_->service.Reject(
if (impl_->service == nullptr) {
if (callback) {
callback(StatusCode::kError);
}
return;
}
impl_->service->Reject(
share_target_id,
[cb = std::move(callback)](
nearby::sharing::NearbySharingService::StatusCodes status) mutable {
@@ -398,7 +546,13 @@ void NearbySharingApi::Reject(int64_t share_target_id,
void NearbySharingApi::Cancel(int64_t share_target_id,
std::function<void(StatusCode)> callback) {
impl_->service.Cancel(
if (impl_->service == nullptr) {
if (callback) {
callback(StatusCode::kError);
}
return;
}
impl_->service->Cancel(
share_target_id,
[cb = std::move(callback)](
nearby::sharing::NearbySharingService::StatusCodes status) mutable {
@@ -408,8 +562,24 @@ void NearbySharingApi::Cancel(int64_t share_target_id,
});
}
void NearbySharingApi::SetDeviceName(const std::string& device_name) {
if (impl_->service == nullptr || device_name.empty()) {
return;
}
if (impl_->service->GetLocalDeviceDataManager() == nullptr) {
return;
}
impl_->service->GetLocalDeviceDataManager()->SetDeviceName(device_name);
}
void NearbySharingApi::Shutdown(std::function<void(StatusCode)> callback) {
impl_->service.Shutdown(
if (impl_->service == nullptr) {
if (callback) {
callback(StatusCode::kError);
}
return;
}
impl_->service->Shutdown(
[this, cb = std::move(callback)](
nearby::sharing::NearbySharingService::StatusCodes status) mutable {
if (status == nearby::sharing::NearbySharingService::StatusCodes::kOk) {
@@ -423,7 +593,10 @@ void NearbySharingApi::Shutdown(std::function<void(StatusCode)> callback) {
}
std::string NearbySharingApi::GetQrCodeUrl() const {
return impl_->service.GetQrCodeUrl();
if (impl_->qr_code_url.empty()) {
impl_->qr_code_url = GenerateQrCodeUrl();
}
return impl_->qr_code_url;
}
std::string NearbySharingApi::StatusCodeToString(StatusCode status) {
+1
View File
@@ -118,6 +118,7 @@ class __attribute__((visibility("default"))) NearbySharingApi {
void Accept(int64_t share_target_id, std::function<void(StatusCode)> callback);
void Reject(int64_t share_target_id, std::function<void(StatusCode)> callback);
void Cancel(int64_t share_target_id, std::function<void(StatusCode)> callback);
void SetDeviceName(const std::string& device_name);
void Shutdown(std::function<void(StatusCode)> callback);
std::string GetQrCodeUrl() const;
-550
View File
@@ -1,550 +0,0 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "connections/implementation/flags/nearby_connections_feature_flags.h"
#include <chrono>
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <vector>
#include "sharing/linux/nearby_sharing_service_linux.h"
#include "sharing/attachment_container.h"
#include "sharing/file_attachment.h"
#include "sharing/share_target.h"
#include "sharing/text_attachment.h"
#include "sharing/transfer_metadata.h"
#include "sharing/share_target_discovered_callback.h"
#include "sharing/transfer_update_callback.h"
#include "internal/base/file_path.h"
#include "internal/base/files.h"
#include "internal/flags/nearby_flags.h"
using namespace nearby::sharing;
using namespace nearby::sharing::linux;
class MyTransferUpdateCallback : public TransferUpdateCallback {
public:
void OnTransferUpdate(const ShareTarget& share_target,
const AttachmentContainer& attachment_container,
const TransferMetadata& transfer_metadata) override {
std::cout << "\n┌─────────────────────────────────────┐" << std::endl;
std::cout << "│ TRANSFER UPDATE │" << std::endl;
std::cout << "├─────────────────────────────────────┤" << std::endl;
std::cout << "│ Device: " << share_target.device_name << std::endl;
std::cout << "│ Target ID: " << share_target.id << " ← USE THIS ID" << std::endl;
std::cout << "│ Status: " << TransferMetadata::StatusToString(transfer_metadata.status()) << std::endl;
std::cout << "│ Progress: " << (transfer_metadata.progress() * 100) << "%" << std::endl;
std::cout << "│ Transferred: " << transfer_metadata.transferred_bytes() << " bytes" << std::endl;
std::cout << "│ Total attachments: " << transfer_metadata.total_attachments_count() << std::endl;
// Track incoming transfer requests
if (transfer_metadata.status() == TransferMetadata::Status::kAwaitingLocalConfirmation) {
std::cout << "├─────────────────────────────────────┤" << std::endl;
std::cout << "│ ⚠️ INCOMING TRANSFER REQUEST │" << std::endl;
std::cout << "│ From: " << share_target.device_name << std::endl;
std::cout << "│ Target ID: " << share_target.id << std::endl;
std::cout << "│ → Press 6 to ACCEPT │" << std::endl;
std::cout << "│ → Press 7 to REJECT │" << std::endl;
pending_target_id_ = share_target.id;
has_pending_request_ = true;
}
// Show completed transfers
if (transfer_metadata.status() == TransferMetadata::Status::kComplete) {
std::cout << "├─────────────────────────────────────┤" << std::endl;
std::cout << "│ ✓ TRANSFER COMPLETE │" << std::endl;
for (const auto& file : attachment_container.GetFileAttachments()) {
std::cout << "│ Received file: " << file.file_name() << std::endl;
}
for (const auto& text : attachment_container.GetTextAttachments()) {
std::cout << "│ Received text: " << text.text_body() << std::endl;
}
has_pending_request_ = false;
}
std::cout << "└─────────────────────────────────────┘" << std::endl;
PrintMenuAtBottom();
}
bool HasPendingRequest() const { return has_pending_request_; }
int64_t GetPendingTargetId() const { return pending_target_id_; }
private:
bool has_pending_request_ = false;
int64_t pending_target_id_ = -1;
void PrintMenuAtBottom() {
std::cout << "\n╔═════════════════════════════════════════════════════════╗" << std::endl;
std::cout << "║ NEARBY SHARING - MENU ║" << std::endl;
std::cout << "╠═════════════════════════════════════════════════════════╣" << std::endl;
std::cout << "║ 1. Start as Receiver │ 6. Accept pending request ║" << std::endl;
std::cout << "║ 2. Start as Sender │ 7. Reject pending request ║" << std::endl;
std::cout << "║ 3. List devices │ 8. Cancel transfer ║" << std::endl;
std::cout << "║ 4. Send file │ 9. Print status ║" << std::endl;
std::cout << "║ 5. Send text │ 0. Exit ║" << std::endl;
std::cout << "╚═════════════════════════════════════════════════════════╝" << std::endl;
std::cout << "Choice: ";
}
};
class MyShareTargetDiscoveredCallback : public ShareTargetDiscoveredCallback {
public:
void OnShareTargetDiscovered(const ShareTarget& share_target) override {
std::cout << "\n┌─────────────────────────────────────┐" << std::endl;
std::cout << "│ 📱 DEVICE DISCOVERED │" << std::endl;
std::cout << "├─────────────────────────────────────┤" << std::endl;
std::cout << "│ ID: " << share_target.id << std::endl;
std::cout << "│ Name: " << share_target.device_name << std::endl;
std::cout << "│ Vendor ID: " << static_cast<int>(share_target.vendor_id) << std::endl;
std::cout << "└─────────────────────────────────────┘" << std::endl;
discovered_targets_.push_back(share_target);
PrintMenuAtBottom();
}
void OnShareTargetLost(const ShareTarget& share_target) override {
std::cout << "\n┌─────────────────────────────────────┐" << std::endl;
std::cout << "│ ❌ DEVICE LOST │" << std::endl;
std::cout << "├─────────────────────────────────────┤" << std::endl;
std::cout << "│ Name: " << share_target.device_name << std::endl;
std::cout << "└─────────────────────────────────────┘" << std::endl;
for (auto it = discovered_targets_.begin(); it != discovered_targets_.end(); ++it) {
if (it->id == share_target.id) {
discovered_targets_.erase(it);
break;
}
}
PrintMenuAtBottom();
}
void OnShareTargetUpdated(const ShareTarget& share_target) override {
std::cout << "\n┌─────────────────────────────────────┐" << std::endl;
std::cout << "│ 🔄 DEVICE UPDATED │" << std::endl;
std::cout << "├─────────────────────────────────────┤" << std::endl;
std::cout << "│ Name: " << share_target.device_name << std::endl;
std::cout << "└─────────────────────────────────────┘" << std::endl;
PrintMenuAtBottom();
}
const std::vector<ShareTarget>& GetDiscoveredTargets() const {
return discovered_targets_;
}
private:
std::vector<ShareTarget> discovered_targets_;
void PrintMenuAtBottom() {
std::cout << "\n╔═════════════════════════════════════════════════════════╗" << std::endl;
std::cout << "║ NEARBY SHARING - MENU ║" << std::endl;
std::cout << "╠═════════════════════════════════════════════════════════╣" << std::endl;
std::cout << "║ 1. Start as Receiver │ 6. Accept pending request ║" << std::endl;
std::cout << "║ 2. Start as Sender │ 7. Reject pending request ║" << std::endl;
std::cout << "║ 3. List devices │ 8. Cancel transfer ║" << std::endl;
std::cout << "║ 4. Send file │ 9. Print status ║" << std::endl;
std::cout << "║ 5. Send text │ 0. Exit ║" << std::endl;
std::cout << "╚═════════════════════════════════════════════════════════╝" << std::endl;
std::cout << "Choice: ";
}
};
class NearbySharingApp {
public:
NearbySharingApp(const std::string& device_name)
: service_(std::make_unique<NearbySharingServiceLinux>(device_name)),
transfer_callback_(std::make_unique<MyTransferUpdateCallback>()),
discovery_callback_(std::make_unique<MyShareTargetDiscoveredCallback>()) {
std::cout << "Nearby Sharing Application initialized with device name: "
<< device_name << std::endl;
}
~NearbySharingApp() {
Shutdown();
}
void StartAsReceiver() {
std::cout << "\n=== Starting as Receiver (Foreground) ===" << std::endl;
service_->RegisterReceiveSurface(
transfer_callback_.get(),
NearbySharingService::ReceiveSurfaceState::kForeground,
Advertisement::BlockedVendorId::kNone,
[this](NearbySharingService::StatusCodes status) {
if (status == NearbySharingService::StatusCodes::kOk) {
std::cout << "Successfully registered as receiver!" << std::endl;
// Display QR code URL
std::string qr_url = service_->GetQrCodeUrl();
if (!qr_url.empty()) {
std::cout << "\n┌──────────────────────────────────────────────────────────────┐" << std::endl;
std::cout << "│ QR CODE URL: │" << std::endl;
std::cout << "" << qr_url;
// Add padding if needed
if (qr_url.length() < 61) {
std::cout << std::string(61 - qr_url.length(), ' ');
}
std::cout << "" << std::endl;
std::cout << "│ │" << std::endl;
std::cout << "│ Scan this with your phone to connect! │" << std::endl;
std::cout << "└──────────────────────────────────────────────────────────────┘" << std::endl;
}
} else {
std::cout << "Failed to register as receiver: "
<< NearbySharingService::StatusCodeToString(status) << std::endl;
}
});
std::cout << "Advertising enabled. Waiting for incoming connections..." << std::endl;
}
void StartAsSender() {
std::cout << "\n=== Starting as Sender (Foreground) ===" << std::endl;
service_->RegisterSendSurface(
transfer_callback_.get(),
discovery_callback_.get(),
NearbySharingService::SendSurfaceState::kForeground,
Advertisement::BlockedVendorId::kNone,
false, // disable_wifi_hotspot
[this](NearbySharingService::StatusCodes status) {
if (status == NearbySharingService::StatusCodes::kOk) {
std::cout << "Successfully registered as sender!" << std::endl;
// Display QR code URL
std::string qr_url = service_->GetQrCodeUrl();
if (!qr_url.empty()) {
std::cout << "\n┌──────────────────────────────────────────────────────────────┐" << std::endl;
std::cout << "│ QR CODE URL: │" << std::endl;
std::cout << "" << qr_url;
// Add padding if needed
if (qr_url.length() < 61) {
std::cout << std::string(61 - qr_url.length(), ' ');
}
std::cout << "" << std::endl;
std::cout << "│ │" << std::endl;
std::cout << "│ Scan this with your phone to connect! │" << std::endl;
std::cout << "└──────────────────────────────────────────────────────────────┘" << std::endl;
}
} else {
std::cout << "Failed to register as sender: "
<< NearbySharingService::StatusCodeToString(status) << std::endl;
}
});
std::cout << "Scanning for nearby devices..." << std::endl;
}
void SendFile(int64_t target_id, const std::string& file_path) {
std::cout << "\n=== Sending File ===" << std::endl;
std::cout << "Target ID: " << target_id << std::endl;
std::cout << "File: " << file_path << std::endl;
nearby::FilePath path(file_path);
auto file_size = nearby::Files::GetFileSize(path);
if (!file_size.has_value()) {
std::cout << "Error: Could not get file size for " << file_path << std::endl;
return;
}
// Use the constructor that accepts size
std::string file_name = path.GetFileName().ToString();
std::string mime_type = ""; // Will be auto-detected from extension
// Create file attachment with proper size
FileAttachment file_attachment(
/*id=*/0, // ID will be auto-generated
/*size=*/static_cast<int64_t>(*file_size),
/*file_name=*/file_name,
/*mime_type=*/mime_type,
/*type=*/service::proto::FileMetadata::UNKNOWN,
/*parent_folder=*/"",
/*batch_id=*/0
);
// Set the file path after construction
file_attachment.set_file_path(path);
auto attachment_container = AttachmentContainer::Builder()
.AddFileAttachment(
std::move(file_attachment))
.Build();
service_->SendAttachments(
target_id,
std::move(attachment_container),
[](NearbySharingService::StatusCodes status) {
if (status == NearbySharingService::StatusCodes::kOk) {
std::cout << "File send initiated successfully!" << std::endl;
} else {
std::cout << "Failed to send file: "
<< NearbySharingService::StatusCodeToString(status) << std::endl;
}
});
}
void SendText(int64_t target_id, const std::string& text) {
std::cout << "\n=== Sending Text ===" << std::endl;
std::cout << "Target ID: " << target_id << std::endl;
std::cout << "Text: " << text << std::endl;
auto attachment_container = AttachmentContainer::Builder()
.AddTextAttachment(TextAttachment(
nearby::sharing::service::proto::
TextMetadata::TEXT,
text,
std::nullopt, // text_title
std::nullopt // mime_type
))
.Build();
service_->SendAttachments(
target_id,
std::move(attachment_container),
[](NearbySharingService::StatusCodes status) {
if (status == NearbySharingService::StatusCodes::kOk) {
std::cout << "Text send initiated successfully!" << std::endl;
} else {
std::cout << "Failed to send text: "
<< NearbySharingService::StatusCodeToString(status) << std::endl;
}
});
}
void AcceptIncomingShare(int64_t target_id) {
std::cout << "\n=== Accepting Incoming Share ===" << std::endl;
std::cout << "Target ID: " << target_id << std::endl;
service_->Accept(
target_id,
[](NearbySharingService::StatusCodes status) {
if (status == NearbySharingService::StatusCodes::kOk) {
std::cout << "Share accepted!" << std::endl;
} else {
std::cout << "Failed to accept share: "
<< NearbySharingService::StatusCodeToString(status) << std::endl;
}
});
}
void AcceptPendingShare() {
if (!transfer_callback_->HasPendingRequest()) {
std::cout << "No pending incoming transfer request!" << std::endl;
return;
}
AcceptIncomingShare(transfer_callback_->GetPendingTargetId());
}
void RejectIncomingShare(int64_t target_id) {
std::cout << "\n=== Rejecting Incoming Share ===" << std::endl;
std::cout << "Target ID: " << target_id << std::endl;
service_->Reject(
target_id,
[](NearbySharingService::StatusCodes status) {
if (status == NearbySharingService::StatusCodes::kOk) {
std::cout << "Share rejected!" << std::endl;
} else {
std::cout << "Failed to reject share: "
<< NearbySharingService::StatusCodeToString(status) << std::endl;
}
});
}
void RejectPendingShare() {
if (!transfer_callback_->HasPendingRequest()) {
std::cout << "No pending incoming transfer request!" << std::endl;
return;
}
RejectIncomingShare(transfer_callback_->GetPendingTargetId());
}
void CancelTransfer(int64_t target_id) {
std::cout << "\n=== Canceling Transfer ===" << std::endl;
std::cout << "Target ID: " << target_id << std::endl;
service_->Cancel(
target_id,
[](NearbySharingService::StatusCodes status) {
if (status == NearbySharingService::StatusCodes::kOk) {
std::cout << "Transfer cancelled!" << std::endl;
} else {
std::cout << "Failed to cancel transfer: "
<< NearbySharingService::StatusCodeToString(status) << std::endl;
}
});
}
void ListDiscoveredDevices() {
std::cout << "\n=== Discovered Devices ===" << std::endl;
const auto& targets = discovery_callback_->GetDiscoveredTargets();
if (targets.empty()) {
std::cout << "No devices found." << std::endl;
} else {
for (const auto& target : targets) {
std::cout << "ID: " << target.id
<< " | Name: " << target.device_name
<< " | Vendor: " << static_cast<int>(target.vendor_id) << std::endl;
}
}
std::cout << "==========================" << std::endl;
}
void PrintStatus() {
std::cout << "\n=== Service Status ===" << std::endl;
std::cout << "Bluetooth Present: " << (service_->IsBluetoothPresent() ? "Yes" : "No") << std::endl;
std::cout << "Bluetooth Powered: " << (service_->IsBluetoothPowered() ? "Yes" : "No") << std::endl;
std::cout << "Is Scanning: " << (service_->IsScanning() ? "Yes" : "No") << std::endl;
std::cout << "Is Transferring: " << (service_->IsTransferring() ? "Yes" : "No") << std::endl;
std::cout << "======================" << std::endl;
}
void Shutdown() {
std::cout << "\n=== Shutting Down ===" << std::endl;
service_->Shutdown([](NearbySharingService::StatusCodes status) {
std::cout << "Shutdown complete: "
<< NearbySharingService::StatusCodeToString(status) << std::endl;
});
}
private:
std::unique_ptr<NearbySharingServiceLinux> service_;
std::unique_ptr<MyTransferUpdateCallback> transfer_callback_;
std::unique_ptr<MyShareTargetDiscoveredCallback> discovery_callback_;
};
void PrintMenu() {
std::cout << "\n╔═════════════════════════════════════════════════════════╗" << std::endl;
std::cout << "║ NEARBY SHARING - MENU ║" << std::endl;
std::cout << "╠═════════════════════════════════════════════════════════╣" << std::endl;
std::cout << "║ 1. Start as Receiver │ 6. Accept pending request ║" << std::endl;
std::cout << "║ 2. Start as Sender │ 7. Reject pending request ║" << std::endl;
std::cout << "║ 3. List devices │ 8. Cancel transfer ║" << std::endl;
std::cout << "║ 4. Send file │ 9. Print status ║" << std::endl;
std::cout << "║ 5. Send text │ 0. Exit ║" << std::endl;
std::cout << "╚═════════════════════════════════════════════════════════╝" << std::endl;
std::cout << "Choice: ";
}
int main(int argc, char* argv[]) {
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
nearby::connections::config_package_nearby::nearby_connections_feature::
kEnableBleL2cap,
true);
nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue(
nearby::connections::config_package_nearby::nearby_connections_feature::
kRefactorBleL2cap,
true);
std::string device_name = "MyLinuxDevice";
if (argc > 1) {
device_name = argv[1];
}
// Clear screen and show header
std::cout << "\033[2J\033[1;1H"; // Clear screen
std::cout << "╔═════════════════════════════════════════════════════════╗" << std::endl;
std::cout << "║ ║" << std::endl;
std::cout << "║ NEARBY SHARING - LINUX APPLICATION ║" << std::endl;
std::cout << "║ Device: " << device_name << std::string(32 - device_name.length(), ' ') << "" << std::endl;
std::cout << "║ ║" << std::endl;
std::cout << "╚═════════════════════════════════════════════════════════╝" << std::endl;
std::cout << "\n[LOG AREA - Updates will appear above the menu]\n" << std::endl;
NearbySharingApp app(device_name);
bool running = true;
while (running) {
PrintMenu();
int choice;
std::cin >> choice;
switch (choice) {
case 1:
app.StartAsReceiver();
break;
case 2:
app.StartAsSender();
std::this_thread::sleep_for(std::chrono::seconds(2));
app.ListDiscoveredDevices();
break;
case 3:
app.ListDiscoveredDevices();
break;
case 4: {
int64_t target_id;
std::string file_path;
std::cout << "Enter target ID: ";
std::cin >> target_id;
std::cout << "Enter file path: ";
std::cin.ignore();
std::getline(std::cin, file_path);
app.SendFile(target_id, file_path);
break;
}
case 5: {
int64_t target_id;
std::string text;
std::cout << "Enter target ID: ";
std::cin >> target_id;
std::cout << "Enter text to send: ";
std::cin.ignore();
std::getline(std::cin, text);
app.SendText(target_id, text);
break;
}
case 6:
app.AcceptPendingShare();
break;
case 7:
app.RejectPendingShare();
break;
case 8: {
int64_t target_id;
std::cout << "Enter target ID to cancel: ";
std::cin >> target_id;
app.CancelTransfer(target_id);
break;
}
case 9:
app.PrintStatus();
break;
case 0:
running = false;
break;
default:
std::cout << "Invalid choice. Please try again." << std::endl;
break;
}
}
std::cout << "\nGoodbye!" << std::endl;
return 0;
}
-28
View File
@@ -1,28 +0,0 @@
# Copyright 2025 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
licenses(["notice"])
cc_binary(
name = "nearby_sharing_app",
srcs = ["nearby_sharing_app.cc"],
deps = [
":nearby_sharing_service_linux",
"//sharing:attachments",
"//sharing:types",
"//internal/platform:base",
"@com_google_absl//absl/strings",
],
visibility = ["//visibility:public"],
)
File diff suppressed because it is too large Load Diff
@@ -1,258 +0,0 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef THIRD_PARTY_NEARBY_SHARING_LINUX_NEARBY_SHARING_SERVICE_LINUX_H_
#define THIRD_PARTY_NEARBY_SHARING_LINUX_NEARBY_SHARING_SERVICE_LINUX_H_
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "connections/advertising_options.h"
#include "connections/connection_options.h"
#include "connections/core.h"
#include "connections/discovery_options.h"
#include "connections/implementation/service_controller_router.h"
#include "connections/listeners.h"
#include "connections/payload.h"
#include "connections/status.h"
#include "connections/strategy.h"
#include "internal/platform/bluetooth_adapter.h"
#include "internal/platform/clock_impl.h"
#include "internal/platform/implementation/platform.h"
#include "sharing/attachment_container.h"
#include "sharing/nearby_sharing_service.h"
#include "sharing/share_target.h"
#include "sharing/share_target_discovered_callback.h"
#include "sharing/transfer_metadata.h"
#include "sharing/transfer_metadata_builder.h"
namespace nearby::sharing::linux {
class NearbySharingServiceLinux : public NearbySharingService {
public:
using StatusCodes = NearbySharingService::StatusCodes;
NearbySharingServiceLinux();
explicit NearbySharingServiceLinux(std::string device_name_override);
~NearbySharingServiceLinux() override;
void AddObserver(Observer* observer) override;
void RemoveObserver(Observer* observer) override;
void Shutdown(
std::function<void(StatusCodes)> status_codes_callback) override;
void RegisterSendSurface(
TransferUpdateCallback* transfer_callback,
ShareTargetDiscoveredCallback* discovery_callback, SendSurfaceState state,
Advertisement::BlockedVendorId blocked_vendor_id,
bool disable_wifi_hotspot,
std::function<void(StatusCodes)> status_codes_callback) override;
void UnregisterSendSurface(
TransferUpdateCallback* transfer_callback,
std::function<void(StatusCodes)> status_codes_callback) override;
void RegisterReceiveSurface(
TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state,
Advertisement::BlockedVendorId vendor_id,
std::function<void(StatusCodes)> status_codes_callback) override;
void UnregisterReceiveSurface(
TransferUpdateCallback* transfer_callback,
std::function<void(StatusCodes)> status_codes_callback) override;
void ClearForegroundReceiveSurfaces(
std::function<void(StatusCodes)> status_codes_callback) override;
bool IsTransferring() const override;
bool IsScanning() const override;
bool IsBluetoothPresent() const override;
bool IsBluetoothPowered() const override;
bool IsExtendedAdvertisingSupported() const override;
bool IsLanConnected() const override;
std::string GetQrCodeUrl() const override;
void SendAttachments(
int64_t share_target_id,
std::unique_ptr<nearby::sharing::AttachmentContainer>
attachment_container,
std::function<void(StatusCodes)> status_codes_callback) override;
void Accept(int64_t share_target_id,
std::function<void(StatusCodes status_codes)>
status_codes_callback) override;
void Reject(int64_t share_target_id,
std::function<void(StatusCodes status_codes)>
status_codes_callback) override;
void Cancel(int64_t share_target_id,
std::function<void(StatusCodes status_codes)>
status_codes_callback) override;
void SetVisibility(proto::DeviceVisibility visibility,
absl::Duration expiration,
absl::AnyInvocable<void(StatusCodes status_code) &&>
callback) override;
std::string Dump() const override;
void UpdateFilePathsInProgress(bool update_file_paths) override;
NearbyShareSettings* GetSettings() override;
NearbyShareLocalDeviceDataManager* GetLocalDeviceDataManager() override;
NearbyShareContactManager* GetContactManager() override;
NearbyShareCertificateManager* GetCertificateManager() override;
AccountManager* GetAccountManager() override;
Clock& GetClock() override;
void SetAlternateServiceUuidForDiscovery(
uint16_t alternate_service_uuid) override;
private:
struct SendSurface {
ShareTargetDiscoveredCallback* discovery_callback = nullptr;
SendSurfaceState state = SendSurfaceState::kUnknown;
bool disable_wifi_hotspot = false;
};
struct ReceiveSurface {
ReceiveSurfaceState state = ReceiveSurfaceState::kUnknown;
Advertisement::BlockedVendorId vendor_id =
Advertisement::BlockedVendorId::kNone;
};
struct TransferState {
nearby::sharing::AttachmentContainer attachments;
TransferUpdateCallback* callback = nullptr;
bool is_incoming = false;
connections::Medium current_medium = connections::Medium::UNKNOWN_MEDIUM;
float max_reported_progress = 0.0f;
// Minimal Nearby Share frame protocol state.
bool paired_key_encryption_sent = false;
bool paired_key_encryption_received = false;
bool paired_key_result_sent = false;
bool paired_key_result_received = false;
bool introduction_sent = false;
bool introduction_received = false;
bool connection_response_sent = false;
bool connection_response_received = false;
bool connection_response_accepted = false;
bool attachment_payloads_sent = false;
// Payload routing state.
std::unordered_set<int64_t> control_payload_ids;
std::unordered_set<int64_t> attachment_payload_ids;
std::unordered_set<int64_t> completed_attachment_payload_ids;
std::unordered_map<int64_t, int64_t> text_attachment_id_by_payload_id;
std::unordered_map<int64_t, int64_t> file_attachment_id_by_payload_id;
size_t expected_attachment_payload_count = 0;
bool transfer_complete_notified = false;
std::vector<connections::Payload> pending_outgoing_payloads;
};
struct ParsedAdvertisement {
ShareTargetType device_type = ShareTargetType::kUnknown;
std::optional<std::string> device_name;
uint8_t vendor_id = 0;
};
void StartAdvertisingIfNeeded();
void StopAdvertising();
void StartDiscoveryIfNeeded();
void StopDiscovery();
std::vector<uint8_t> BuildAdvertisement(
const std::optional<std::string>& device_name,
ShareTargetType device_type, uint8_t vendor_id) const;
std::optional<ParsedAdvertisement> ParseAdvertisement(
absl::Span<const uint8_t> endpoint_info) const;
void NotifyShareTargetDiscovered(const ShareTarget& share_target);
void NotifyShareTargetUpdated(const ShareTarget& share_target);
void NotifyShareTargetLost(const ShareTarget& share_target);
void NotifyTransferUpdate(const ShareTarget& share_target,
const TransferState& transfer_state,
const TransferMetadata& metadata);
TransferUpdateCallback* PickSendTransferCallback() const;
TransferUpdateCallback* PickReceiveTransferCallback() const;
std::optional<std::string> GetEndpointIdForTarget(
int64_t share_target_id) const;
std::optional<ShareTarget> GetShareTarget(
absl::string_view endpoint_id) const;
void HandleIncomingConnectionInitiated(
const std::string& endpoint_id,
const connections::ConnectionResponseInfo& info);
void HandleOutgoingConnectionInitiated(
const std::string& endpoint_id,
const connections::ConnectionResponseInfo& info);
void HandleConnectionAccepted(const std::string& endpoint_id,
bool is_incoming);
void HandleConnectionRejected(const std::string& endpoint_id,
connections::Status status, bool is_incoming);
void HandleConnectionDisconnected(const std::string& endpoint_id);
connections::PayloadListener MakePayloadListener(bool is_incoming);
StatusCodes StatusFromConnections(connections::Status status) const;
std::string device_name_override_;
std::unique_ptr<::nearby::api::DeviceInfo> device_info_;
BluetoothAdapter bluetooth_adapter_;
ClockImpl clock_;
std::unique_ptr<connections::ServiceControllerRouter> router_;
std::unique_ptr<connections::Core> core_;
std::unordered_set<Observer*> observers_;
std::unordered_map<TransferUpdateCallback*, SendSurface> send_surfaces_;
std::unordered_map<TransferUpdateCallback*, ReceiveSurface> receive_surfaces_;
std::unordered_map<std::string, ShareTarget> endpoint_to_target_;
std::unordered_map<int64_t, std::string> target_id_to_endpoint_;
std::unordered_map<std::string, TransferState> active_transfers_;
std::optional<uint16_t> alternate_service_uuid_;
bool is_scanning_ = false;
bool is_advertising_ = false;
bool is_transferring_ = false;
int64_t next_share_target_id_ = 1;
bool last_advertise_with_name_ = false;
uint8_t last_advertise_vendor_id_ = 0;
// QR code related
mutable std::string qr_code_url_;
std::string GenerateQrCodeUrl() const;
};
} // namespace nearby::sharing::linux
#endif // THIRD_PARTY_NEARBY_SHARING_LINUX_NEARBY_SHARING_SERVICE_LINUX_H_
@@ -73,6 +73,9 @@ FileShareTrayController::FileShareTrayController(QObject* parent)
FileShareTrayController::~FileShareTrayController() {
stop();
if (service_) {
service_->Shutdown([](NearbySharingApi::StatusCode) {});
}
}
void FileShareTrayController::CreateService() {
@@ -181,19 +184,6 @@ void FileShareTrayController::AttachServiceListeners() {
file_name = pending_send_file_name_;
}
qInfo().noquote()
<< QStringLiteral(
"Transfer update target=%1 name=\"%2\" status=%3 "
"progress=%4 bytes=%5 attachments=%6/%7 direction=%8")
.arg(update.share_target_id)
.arg(name)
.arg(status)
.arg(QString::number(update.progress, 'f', 4))
.arg(update.transferred_bytes)
.arg(update.transferred_attachments)
.arg(update.total_attachments)
.arg(direction);
UpsertTransfer(update.share_target_id, name, status, update.progress,
update.transferred_bytes, direction, file_name);
SetStatus(QStringLiteral("%1 (%2)")
@@ -335,6 +325,15 @@ void FileShareTrayController::setDeviceName(const QString& device_name) {
device_name_ = trimmed;
emit deviceNameChanged();
SaveSettings();
if (service_) {
//service_->SetDeviceName(device_name_.toStdString());
//qr_code_url_ = QString::fromStdString(service_->GetQrCodeUrl());
//UpdateQrCodeData();
//emit qrCodeUrlChanged();
//emit qrCodeChanged();
service_->Shutdown([](NearbySharingApi::StatusCode) {});
service_.reset();
}
CreateService();
if (was_running) {
@@ -382,7 +381,6 @@ void FileShareTrayController::stop() {
service_->StopSendMode([](NearbySharingApi::StatusCode) {});
service_->StopReceiveMode([](NearbySharingApi::StatusCode) {});
service_->Shutdown([](NearbySharingApi::StatusCode) {});
discovered_targets_.clear();
discovered_row_by_target_.clear();
-251
View File
@@ -1,251 +0,0 @@
// Copyright 2025 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Simple example: Send a text message to nearby device
//
// Usage:
// Terminal 1 (Receiver): ./simple_receiver
// Terminal 2 (Sender): ./simple_sender "Hello World"
#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <chrono>
#include "sharing/linux/nearby_sharing_service_linux.h"
#include "sharing/attachment_container.h"
#include "sharing/text_attachment.h"
#include "sharing/share_target.h"
#include "sharing/transfer_metadata.h"
#include "sharing/transfer_update_callback.h"
#include "sharing/share_target_discovered_callback.h"
using namespace nearby::sharing;
using namespace nearby::sharing::linux;
// Simple callback that automatically accepts incoming transfers
class SimpleReceiverCallback : public TransferUpdateCallback {
public:
explicit SimpleReceiverCallback(NearbySharingServiceLinux* service)
: service_(service) {}
void OnTransferUpdate(const ShareTarget& share_target,
const AttachmentContainer& attachment_container,
const TransferMetadata& transfer_metadata) override {
std::cout << "\n[Receiver] Transfer Update from: " << share_target.device_name << std::endl;
std::cout << "[Receiver] Status: "
<< TransferMetadata::StatusToString(transfer_metadata.status()) << std::endl;
// Auto-accept incoming transfers
if (transfer_metadata.status() == TransferMetadata::Status::kAwaitingLocalConfirmation) {
std::cout << "[Receiver] Auto-accepting transfer..." << std::endl;
service_->Accept(share_target.id, [](auto status) {
std::cout << "[Receiver] Accept status: "
<< NearbySharingService::StatusCodeToString(status) << std::endl;
});
}
// Show received content when complete
if (transfer_metadata.status() == TransferMetadata::Status::kComplete) {
std::cout << "\n[Receiver] ✓ Transfer Complete!" << std::endl;
// Display received text
for (const auto& text : attachment_container.GetTextAttachments()) {
std::cout << "[Receiver] Received text: \"" << text.text_body() << "\"" << std::endl;
}
// Display received files
for (const auto& file : attachment_container.GetFileAttachments()) {
std::cout << "[Receiver] Received file: " << file.file_name() << std::endl;
}
}
}
private:
NearbySharingServiceLinux* service_;
};
// Callback for discovering nearby devices
class SimpleSenderCallback : public ShareTargetDiscoveredCallback {
public:
void OnShareTargetDiscovered(const ShareTarget& share_target) override {
std::cout << "\n[Sender] Found device: " << share_target.device_name
<< " (ID: " << share_target.id << ")" << std::endl;
discovered_target_ = share_target;
has_target_ = true;
}
void OnShareTargetLost(const ShareTarget& share_target) override {
std::cout << "[Sender] Lost device: " << share_target.device_name << std::endl;
if (has_target_ && discovered_target_.id == share_target.id) {
has_target_ = false;
}
}
void OnShareTargetUpdated(const ShareTarget& share_target) override {}
bool HasTarget() const { return has_target_; }
const ShareTarget& GetTarget() const { return discovered_target_; }
private:
ShareTarget discovered_target_;
bool has_target_ = false;
};
// Transfer progress callback for sender
class SimpleSenderTransferCallback : public TransferUpdateCallback {
public:
void OnTransferUpdate(const ShareTarget& share_target,
const AttachmentContainer& attachment_container,
const TransferMetadata& transfer_metadata) override {
std::cout << "[Sender] Transfer to " << share_target.device_name
<< ": " << TransferMetadata::StatusToString(transfer_metadata.status())
<< " (" << (transfer_metadata.progress() * 100) << "%)" << std::endl;
if (transfer_metadata.status() == TransferMetadata::Status::kComplete) {
std::cout << "[Sender] ✓ Transfer Complete!" << std::endl;
transfer_complete_ = true;
} else if (transfer_metadata.status() == TransferMetadata::Status::kFailed) {
std::cout << "[Sender] ✗ Transfer Failed!" << std::endl;
transfer_complete_ = true;
}
}
bool IsTransferComplete() const { return transfer_complete_; }
private:
bool transfer_complete_ = false;
};
int main(int argc, char* argv[]) {
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " <receiver|sender> [message]" << std::endl;
std::cout << "Examples:" << std::endl;
std::cout << " " << argv[0] << " receiver # Start as receiver" << std::endl;
std::cout << " " << argv[0] << " sender \"Hello!\" # Send text message" << std::endl;
return 1;
}
std::string mode = argv[1];
if (mode == "receiver") {
// ============= RECEIVER MODE =============
std::cout << "=== Nearby Sharing Receiver ===" << std::endl;
NearbySharingServiceLinux service("Receiver-Device");
SimpleReceiverCallback callback(&service);
// Register as a receiver (advertise to nearby devices)
service.RegisterReceiveSurface(
&callback,
NearbySharingService::ReceiveSurfaceState::kForeground,
Advertisement::BlockedVendorId::kNone,
[](auto status) {
if (status == NearbySharingService::StatusCodes::kOk) {
std::cout << "[Receiver] ✓ Advertising started" << std::endl;
std::cout << "[Receiver] Waiting for incoming transfers..." << std::endl;
} else {
std::cout << "[Receiver] ✗ Failed to start: "
<< NearbySharingService::StatusCodeToString(status) << std::endl;
}
});
// Keep running to receive transfers
std::cout << "\nPress Ctrl+C to exit..." << std::endl;
while (true) {
std::this_thread::sleep_for(std::chrono::seconds(1));
}
} else if (mode == "sender") {
// ============= SENDER MODE =============
std::string message = "Hello from Nearby Sharing!";
if (argc > 2) {
message = argv[2];
}
std::cout << "=== Nearby Sharing Sender ===" << std::endl;
std::cout << "[Sender] Message to send: \"" << message << "\"" << std::endl;
NearbySharingServiceLinux service("Sender-Device");
SimpleSenderCallback discovery_callback;
SimpleSenderTransferCallback transfer_callback;
// Register as sender (scan for nearby devices)
service.RegisterSendSurface(
&transfer_callback,
&discovery_callback,
NearbySharingService::SendSurfaceState::kForeground,
Advertisement::BlockedVendorId::kNone,
false,
[](auto status) {
if (status == NearbySharingService::StatusCodes::kOk) {
std::cout << "[Sender] ✓ Scanning started" << std::endl;
} else {
std::cout << "[Sender] ✗ Failed to start: "
<< NearbySharingService::StatusCodeToString(status) << std::endl;
}
});
// Wait for device discovery
std::cout << "[Sender] Scanning for nearby devices..." << std::endl;
int wait_time = 0;
while (!discovery_callback.HasTarget() && wait_time < 10) {
std::this_thread::sleep_for(std::chrono::seconds(1));
wait_time++;
std::cout << "." << std::flush;
}
std::cout << std::endl;
if (!discovery_callback.HasTarget()) {
std::cout << "[Sender] ✗ No devices found. Make sure receiver is running!" << std::endl;
return 1;
}
// Create text attachment
auto attachment_container = std::make_unique<AttachmentContainer>();
attachment_container->AddTextAttachment(TextAttachment(
nearby::sharing::service::proto::TextMetadata::TEXT,
message,
std::nullopt,
std::nullopt
));
// Send to discovered device
const auto& target = discovery_callback.GetTarget();
std::cout << "\n[Sender] Sending to: " << target.device_name << std::endl;
service.SendAttachments(
target.id,
std::move(attachment_container),
[](auto status) {
std::cout << "[Sender] Send initiated: "
<< NearbySharingService::StatusCodeToString(status) << std::endl;
});
// Wait for transfer to complete
std::cout << "[Sender] Transferring..." << std::endl;
while (!transfer_callback.IsTransferComplete()) {
std::this_thread::sleep_for(std::chrono::milliseconds(500));
}
std::cout << "\n[Sender] Done!" << std::endl;
} else {
std::cout << "Invalid mode. Use 'receiver' or 'sender'" << std::endl;
return 1;
}
return 0;
}
+1 -2
View File
@@ -17,7 +17,6 @@
#include <memory>
#include <utility>
#include "location/nearby/sharing/lib/rpc/grpc_async_client_factory.h"
#include "internal/analytics/event_logger.h"
#include "internal/platform/task_runner.h"
#include "sharing/analytics/analytics_recorder.h"
@@ -43,7 +42,7 @@ NearbySharingService* NearbySharingServiceFactory::CreateSharingService(
analytics::AnalyticsRecorder* analytics_recorder,
::nearby::analytics::EventLogger* event_logger, bool supports_file_sync) {
if (nearby_sharing_service_ != nullptr) {
return nullptr;
return nearby_sharing_service_.get();
}
context_ =
+7 -2
View File
@@ -17,13 +17,18 @@
#include <memory>
#include "location/nearby/sharing/lib/rpc/grpc_async_client_factory.h"
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "internal/analytics/event_logger.h"
#include "sharing/analytics/analytics_recorder.h"
#include "sharing/internal/api/sharing_platform.h"
#include "sharing/internal/public/context.h"
#include "sharing/nearby_sharing_service.h"
#if defined(__linux__)
#include "sharing/linux/stubs/grpc_async_client_factory.h"
#include "sharing/linux/stubs/sharing_rpc_client.h"
#else
#include "location/nearby/sharing/lib/rpc/grpc_async_client_factory.h"
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#endif
namespace nearby::sharing {
-1
View File
@@ -31,7 +31,6 @@
#include <utility>
#include <vector>
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "absl/base/nullability.h"
#include "absl/container/flat_hash_map.h"
#include "absl/functional/any_invocable.h"
+7 -2
View File
@@ -27,8 +27,6 @@
#include <tuple>
#include <vector>
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "location/nearby/sharing/lib/sync/sync_manager.h"
#include "absl/base/nullability.h"
#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
@@ -76,6 +74,13 @@
#include "sharing/transfer_metadata.h"
#include "sharing/transfer_update_callback.h"
#include "sharing/wrapped_share_target_discovered_callback.h"
#if defined(__linux__)
#include "sharing/linux/stubs/sharing_rpc_client.h"
#include "sharing/linux/stubs/sync_manager.h"
#else
#include "location/nearby/sharing/lib/rpc/sharing_rpc_client.h"
#include "location/nearby/sharing/lib/sync/sync_manager.h"
#endif
namespace nearby::sharing {
class NearbyShareContactManager;