From 21b2c4c3c175dff4164257c8fd12e877d4b3edff Mon Sep 17 00:00:00 2001 From: Lasan Mahaliyana Date: Mon, 16 Mar 2026 00:16:38 +0530 Subject: [PATCH] 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 --- sharing/BUILD | 10 +- sharing/certificates/BUILD | 14 +- .../fake_nearby_share_certificate_manager.cc | 6 +- .../fake_nearby_share_certificate_manager.h | 6 +- .../nearby_share_certificate_manager_impl.cc | 14 +- .../nearby_share_certificate_manager_impl.h | 8 +- sharing/contacts/BUILD | 4 +- .../nearby_share_contact_manager_impl.cc | 6 +- .../nearby_share_contact_manager_impl.h | 8 +- sharing/incoming_share_session.cc | 7 +- sharing/incoming_share_session.h | 3 +- sharing/internal/api/BUILD | 4 +- sharing/internal/api/preference_manager.h | 18 +- .../internal/base/utf_string_conversions.h | 43 +- sharing/internal/public/BUILD | 1 - sharing/internal/test/BUILD | 2 - .../internal/test/fake_preference_manager.cc | 2 - .../internal/test/fake_preference_manager.h | 2 - sharing/linux/BUILD | 187 +- sharing/linux/nearby_connections_qt_facade.cc | 473 ----- sharing/linux/nearby_connections_qt_facade.h | 228 --- .../linux/nearby_connections_service_linux.cc | 445 ----- .../linux/nearby_connections_service_linux.h | 114 -- sharing/linux/nearby_sharing_api.cc | 219 ++- sharing/linux/nearby_sharing_api.h | 1 + sharing/linux/nearby_sharing_app.cc | 550 ------ sharing/linux/nearby_sharing_app_BUILD | 28 - sharing/linux/nearby_sharing_service_linux.cc | 1561 ----------------- sharing/linux/nearby_sharing_service_linux.h | 258 --- .../file_share_tray_controller.cc | 26 +- sharing/linux/simple_example.cc | 251 --- sharing/nearby_sharing_service_factory.cc | 3 +- sharing/nearby_sharing_service_factory.h | 9 +- sharing/nearby_sharing_service_impl.cc | 1 - sharing/nearby_sharing_service_impl.h | 9 +- 35 files changed, 367 insertions(+), 4154 deletions(-) delete mode 100644 sharing/linux/nearby_connections_qt_facade.cc delete mode 100644 sharing/linux/nearby_connections_qt_facade.h delete mode 100644 sharing/linux/nearby_connections_service_linux.cc delete mode 100644 sharing/linux/nearby_connections_service_linux.h delete mode 100644 sharing/linux/nearby_sharing_app.cc delete mode 100644 sharing/linux/nearby_sharing_app_BUILD delete mode 100644 sharing/linux/nearby_sharing_service_linux.cc delete mode 100644 sharing/linux/nearby_sharing_service_linux.h delete mode 100644 sharing/linux/simple_example.cc diff --git a/sharing/BUILD b/sharing/BUILD index 6aadfd1e..61c9d32d 100644 --- a/sharing/BUILD +++ b/sharing/BUILD @@ -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", diff --git a/sharing/certificates/BUILD b/sharing/certificates/BUILD index f18cfbd8..a0f085b6 100644 --- a/sharing/certificates/BUILD +++ b/sharing/certificates/BUILD @@ -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", diff --git a/sharing/certificates/fake_nearby_share_certificate_manager.cc b/sharing/certificates/fake_nearby_share_certificate_manager.cc index d20d0a9d..459609b1 100644 --- a/sharing/certificates/fake_nearby_share_certificate_manager.cc +++ b/sharing/certificates/fake_nearby_share_certificate_manager.cc @@ -23,7 +23,6 @@ #include #include -#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" diff --git a/sharing/certificates/fake_nearby_share_certificate_manager.h b/sharing/certificates/fake_nearby_share_certificate_manager.h index 6b2bd504..c2508306 100644 --- a/sharing/certificates/fake_nearby_share_certificate_manager.h +++ b/sharing/certificates/fake_nearby_share_certificate_manager.h @@ -24,7 +24,6 @@ #include #include -#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 { diff --git a/sharing/certificates/nearby_share_certificate_manager_impl.cc b/sharing/certificates/nearby_share_certificate_manager_impl.cc index fe33848a..5b68afe8 100644 --- a/sharing/certificates/nearby_share_certificate_manager_impl.cc +++ b/sharing/certificates/nearby_share_certificate_manager_impl.cc @@ -28,10 +28,7 @@ #include #include -#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 { diff --git a/sharing/certificates/nearby_share_certificate_manager_impl.h b/sharing/certificates/nearby_share_certificate_manager_impl.h index 20ad389d..2de41713 100644 --- a/sharing/certificates/nearby_share_certificate_manager_impl.h +++ b/sharing/certificates/nearby_share_certificate_manager_impl.h @@ -23,7 +23,6 @@ #include #include -#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; diff --git a/sharing/contacts/BUILD b/sharing/contacts/BUILD index 61b4807b..04f9d8a8 100644 --- a/sharing/contacts/BUILD +++ b/sharing/contacts/BUILD @@ -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", diff --git a/sharing/contacts/nearby_share_contact_manager_impl.cc b/sharing/contacts/nearby_share_contact_manager_impl.cc index 37c9df39..d142e277 100644 --- a/sharing/contacts/nearby_share_contact_manager_impl.cc +++ b/sharing/contacts/nearby_share_contact_manager_impl.cc @@ -23,7 +23,6 @@ #include #include -#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" diff --git a/sharing/contacts/nearby_share_contact_manager_impl.h b/sharing/contacts/nearby_share_contact_manager_impl.h index 43e23592..06e31cbc 100644 --- a/sharing/contacts/nearby_share_contact_manager_impl.h +++ b/sharing/contacts/nearby_share_contact_manager_impl.h @@ -17,7 +17,6 @@ #include -#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 executor_ = nullptr; }; diff --git a/sharing/incoming_share_session.cc b/sharing/incoming_share_session.cc index 870c7787..669cff8f 100644 --- a/sharing/incoming_share_session.cc +++ b/sharing/incoming_share_session.cc @@ -24,8 +24,6 @@ #include #include -#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" diff --git a/sharing/incoming_share_session.h b/sharing/incoming_share_session.h index 5a9d91ee..73a7ce14 100644 --- a/sharing/incoming_share_session.h +++ b/sharing/incoming_share_session.h @@ -21,7 +21,6 @@ #include #include -#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 { diff --git a/sharing/internal/api/BUILD b/sharing/internal/api/BUILD index 9fb16437..897f6c6f 100644 --- a/sharing/internal/api/BUILD +++ b/sharing/internal/api/BUILD @@ -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", diff --git a/sharing/internal/api/preference_manager.h b/sharing/internal/api/preference_manager.h index ae3b5352..1cd38bb7 100644 --- a/sharing/internal/api/preference_manager.h +++ b/sharing/internal/api/preference_manager.h @@ -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 diff --git a/sharing/internal/base/utf_string_conversions.h b/sharing/internal/base/utf_string_conversions.h index 545953d8..362ac45c 100644 --- a/sharing/internal/base/utf_string_conversions.h +++ b/sharing/internal/base/utf_string_conversions.h @@ -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 +#include + #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(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(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_ diff --git a/sharing/internal/public/BUILD b/sharing/internal/public/BUILD index 42b6137b..c7e76cc9 100644 --- a/sharing/internal/public/BUILD +++ b/sharing/internal/public/BUILD @@ -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", diff --git a/sharing/internal/test/BUILD b/sharing/internal/test/BUILD index 0342ae4c..b377f056 100644 --- a/sharing/internal/test/BUILD +++ b/sharing/internal/test/BUILD @@ -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", diff --git a/sharing/internal/test/fake_preference_manager.cc b/sharing/internal/test/fake_preference_manager.cc index cac1bb32..84955eb8 100644 --- a/sharing/internal/test/fake_preference_manager.cc +++ b/sharing/internal/test/fake_preference_manager.cc @@ -22,8 +22,6 @@ #include #include -#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" diff --git a/sharing/internal/test/fake_preference_manager.h b/sharing/internal/test/fake_preference_manager.h index 88f7eb1e..4b0181f9 100644 --- a/sharing/internal/test/fake_preference_manager.h +++ b/sharing/internal/test/fake_preference_manager.h @@ -23,8 +23,6 @@ #include #include -#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" diff --git a/sharing/linux/BUILD b/sharing/linux/BUILD index 33c011df..45ff2759 100644 --- a/sharing/linux/BUILD +++ b/sharing/linux/BUILD @@ -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", ], ) diff --git a/sharing/linux/nearby_connections_qt_facade.cc b/sharing/linux/nearby_connections_qt_facade.cc deleted file mode 100644 index 5afed8e6..00000000 --- a/sharing/linux/nearby_connections_qt_facade.cc +++ /dev/null @@ -1,473 +0,0 @@ -#include "sharing/linux/nearby_connections_qt_facade.h" - -#include -#include - -#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 g_next_payload_id{1}; - -int64_t NextPayloadId() { return g_next_payload_id.fetch_add(1); } - -std::string DecodePeerName(const std::vector& 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 ToNativeStatusCallback( - std::function 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 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( - payload_id, std::move(payload.bytes)); - case Facade::Payload::Type::kFile: - return std::make_unique( - 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()) {} - - std::unique_ptr service; -}; - -NearbyConnectionsQtFacade::NearbyConnectionsQtFacade() - : impl_(std::make_unique()) {} - -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 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& endpoint_info, - const AdvertisingOptions& advertising_options, - ConnectionListener advertising_listener, - std::function 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 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 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 callback) { - impl_->service->StopDiscovery(service_id, - ToNativeStatusCallback(std::move(callback))); -} - -void NearbyConnectionsQtFacade::RequestConnection( - const std::string& service_id, const std::vector& endpoint_info, - const std::string& endpoint_id, const ConnectionOptions& connection_options, - ConnectionListener connection_listener, std::function 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 callback) { - impl_->service->DisconnectFromEndpoint( - service_id, endpoint_id, ToNativeStatusCallback(std::move(callback))); -} - -void NearbyConnectionsQtFacade::SendPayload( - const std::string& service_id, const std::vector& endpoint_ids, - Payload payload, std::function 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 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 callback) { - impl_->service->AcceptConnection( - service_id, endpoint_id, ToNativePayloadListener(std::move(payload_listener)), - ToNativeStatusCallback(std::move(callback))); -} - -void NearbyConnectionsQtFacade::StopAllEndpoints( - std::function callback) { - impl_->service->StopAllEndpoints(ToNativeStatusCallback(std::move(callback))); -} - -} // namespace nearby::sharing diff --git a/sharing/linux/nearby_connections_qt_facade.h b/sharing/linux/nearby_connections_qt_facade.h deleted file mode 100644 index 89ce9cb0..00000000 --- a/sharing/linux/nearby_connections_qt_facade.h +++ /dev/null @@ -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 - -#include -#include -#include -#include - -// 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 endpoint_info; - std::string peer_name; - }; - - struct DiscoveredEndpointInfo { - std::vector 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 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 - initiated_cb; - std::function accepted_cb; - std::function rejected_cb; - std::function disconnected_cb; - std::function bandwidth_changed_cb; - }; - - struct DiscoveryListener { - std::function - endpoint_found_cb; - std::function endpoint_lost_cb; - std::function - endpoint_distance_changed_cb; - }; - - struct PayloadListener { - std::function payload_cb; - std::function - 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 bytes) const; - - void StartAdvertising(const std::string &service_id, - const std::vector &endpoint_info, - const AdvertisingOptions &advertising_options, - ConnectionListener advertising_listener, - std::function callback); - void StopAdvertising(const std::string &service_id, - std::function callback); - - void StartDiscovery(const std::string &service_id, - const DiscoveryOptions &discovery_options, - DiscoveryListener discovery_listener, - std::function callback); - void StopDiscovery(const std::string &service_id, - std::function callback); - - void RequestConnection(const std::string &service_id, - const std::vector &endpoint_info, - const std::string &endpoint_id, - const ConnectionOptions &connection_options, - ConnectionListener connection_listener, - std::function callback); - - void DisconnectFromEndpoint(const std::string &service_id, - const std::string &endpoint_id, - std::function callback); - - void SendPayload(const std::string &service_id, - const std::vector &endpoint_ids, - Payload payload, std::function callback); - void InitiateBandwidthUpgrade(const std::string &service_id, - const std::string &endpoint_id, - std::function callback); - - void AcceptConnection(const std::string &service_id, - const std::string &endpoint_id, - PayloadListener payload_listener, - std::function callback); - - void StopAllEndpoints(std::function callback); - -private: - class Impl; - std::unique_ptr impl_; -}; -} // namespace sharing -} // namespace nearby - -#endif // SHARING_LINUX_NEARBY_CONNECTIONS_QT_FACADE_H_ diff --git a/sharing/linux/nearby_connections_service_linux.cc b/sharing/linux/nearby_connections_service_linux.cc deleted file mode 100644 index 9a408331..00000000 --- a/sharing/linux/nearby_connections_service_linux.cc +++ /dev/null @@ -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 - -#include -#include -#include -#include -#include -#include -#include - -#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.value); -} - -NcResultCallback MakeResultCallback(std::function 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(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 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( - 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( - 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& endpoint_info, - const AdvertisingOptions& advertising_options, - ConnectionListener advertising_listener, - std::function 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)); - }; - - core_.StartAdvertising(service_id, options, std::move(request_info), - MakeResultCallback(std::move(callback))); -} - -void NearbyConnectionsServiceLinux::StopAdvertising( - absl::string_view service_id, std::function callback) { - static_cast(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 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(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(distance_info)); - }; - - core_.StartDiscovery(service_id, options, std::move(listener), - MakeResultCallback(std::move(callback))); -} - -void NearbyConnectionsServiceLinux::StopDiscovery( - absl::string_view service_id, std::function callback) { - static_cast(service_id); - core_.StopDiscovery(MakeResultCallback(std::move(callback))); -} - -void NearbyConnectionsServiceLinux::RequestConnection( - absl::string_view service_id, const std::vector& endpoint_info, - absl::string_view endpoint_id, const ConnectionOptions& connection_options, - ConnectionListener connection_listener, - std::function callback) { - static_cast(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)); - }; - - 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 callback) { - static_cast(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 endpoint_ids, - std::unique_ptr payload, - std::function callback) { - static_cast(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 callback) { - static_cast(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 callback) { - static_cast(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 callback) { - static_cast(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(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 callback) { - payload_listeners_.clear(); - core_.StopAllEndpoints(MakeResultCallback(std::move(callback))); -} - -void NearbyConnectionsServiceLinux::SetCustomSavePath( - absl::string_view path, std::function 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(core_).Dump(); -} - -} // namespace sharing::linux -} // namespace nearby diff --git a/sharing/linux/nearby_connections_service_linux.h b/sharing/linux/nearby_connections_service_linux.h deleted file mode 100644 index 05ddcd89..00000000 --- a/sharing/linux/nearby_connections_service_linux.h +++ /dev/null @@ -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 - -#include -#include -#include -#include - -#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& endpoint_info, - const AdvertisingOptions& advertising_options, - ConnectionListener advertising_listener, - std::function callback) override; - void StopAdvertising(absl::string_view service_id, - std::function callback) override; - - void StartDiscovery(absl::string_view service_id, - const DiscoveryOptions& discovery_options, - DiscoveryListener discovery_listener, - std::function callback) override; - void StopDiscovery(absl::string_view service_id, - std::function callback) override; - - void RequestConnection(absl::string_view service_id, - const std::vector& endpoint_info, - absl::string_view endpoint_id, - const ConnectionOptions& connection_options, - ConnectionListener connection_listener, - std::function callback) override; - - void DisconnectFromEndpoint( - absl::string_view service_id, absl::string_view endpoint_id, - std::function callback) override; - - void SendPayload(absl::string_view service_id, - absl::Span endpoint_ids, - std::unique_ptr payload, - std::function callback) override; - void CancelPayload(absl::string_view service_id, int64_t payload_id, - std::function callback) override; - - void InitiateBandwidthUpgrade( - absl::string_view service_id, absl::string_view endpoint_id, - std::function callback) override; - - void AcceptConnection(absl::string_view service_id, - absl::string_view endpoint_id, - PayloadListener payload_listener, - std::function callback) override; - - void StopAllEndpoints(std::function callback) override; - - void SetCustomSavePath(absl::string_view path, - std::function 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 payload_listeners_; -}; - -} // namespace sharing::linux -} // namespace nearby - -#endif // THIRD_PARTY_NEARBY_SHARING_LINUX_NEARBY_CONNECTIONS_SERVICE_LINUX_H_ diff --git a/sharing/linux/nearby_sharing_api.cc b/sharing/linux/nearby_sharing_api.cc index e6c5da83..2eb37bb3 100644 --- a/sharing/linux/nearby_sharing_api.cc +++ b/sharing/linux/nearby_sharing_api.cc @@ -3,15 +3,27 @@ #include #include #include +#include #include +#include +#include +#include + +#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 x_bytes(32, 0); + const int x_len = BN_num_bytes(x); + if (x_len > static_cast(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 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(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 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 callback) { } void NearbySharingApi::StopSendMode(std::function 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 callback) { } void NearbySharingApi::StartReceiveMode(std::function 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 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 callback) void NearbySharingApi::SendFile(int64_t share_target_id, const std::string& file_path, std::function 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 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 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 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 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 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) { diff --git a/sharing/linux/nearby_sharing_api.h b/sharing/linux/nearby_sharing_api.h index 687131d6..ba140f9a 100644 --- a/sharing/linux/nearby_sharing_api.h +++ b/sharing/linux/nearby_sharing_api.h @@ -118,6 +118,7 @@ class __attribute__((visibility("default"))) NearbySharingApi { void Accept(int64_t share_target_id, std::function callback); void Reject(int64_t share_target_id, std::function callback); void Cancel(int64_t share_target_id, std::function callback); + void SetDeviceName(const std::string& device_name); void Shutdown(std::function callback); std::string GetQrCodeUrl() const; diff --git a/sharing/linux/nearby_sharing_app.cc b/sharing/linux/nearby_sharing_app.cc deleted file mode 100644 index c62abdf2..00000000 --- a/sharing/linux/nearby_sharing_app.cc +++ /dev/null @@ -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 -#include -#include -#include -#include -#include - -#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(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& GetDiscoveredTargets() const { - return discovered_targets_; - } - - private: - std::vector 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(device_name)), - transfer_callback_(std::make_unique()), - discovery_callback_(std::make_unique()) { - 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(*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(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 service_; - std::unique_ptr transfer_callback_; - std::unique_ptr 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; -} diff --git a/sharing/linux/nearby_sharing_app_BUILD b/sharing/linux/nearby_sharing_app_BUILD deleted file mode 100644 index 80252d43..00000000 --- a/sharing/linux/nearby_sharing_app_BUILD +++ /dev/null @@ -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"], -) diff --git a/sharing/linux/nearby_sharing_service_linux.cc b/sharing/linux/nearby_sharing_service_linux.cc deleted file mode 100644 index 149650a7..00000000 --- a/sharing/linux/nearby_sharing_service_linux.cc +++ /dev/null @@ -1,1561 +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 "nearby_sharing_service_linux.h" -#include "sharing/proto/enums.pb.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "absl/strings/escaping.h" -#include "absl/strings/string_view.h" -#include "absl/time/time.h" -#include "connections/advertising_options.h" -#include "connections/connection_options.h" -#include "connections/discovery_options.h" -#include "connections/listeners.h" -#include "connections/medium_selector.h" -#include "connections/payload.h" -#include "connections/status.h" -#include "connections/strategy.h" -#include "internal/base/files.h" -#include "internal/crypto_cros/ec_private_key.h" -#include "internal/platform/byte_array.h" -#include "internal/platform/file.h" -#include "internal/platform/logging.h" -#include "sharing/certificates/common.h" -#include "sharing/proto/wire_format.pb.h" -#include -#include -#include - -namespace nearby::sharing::linux { -namespace { -constexpr char kServiceId[] = "NearbySharing"; -const connections::Strategy kStrategy = connections::Strategy::kP2pPointToPoint; -constexpr uint8_t kAdvertisementSaltSize = 2; -constexpr uint8_t kAdvertisementMetadataKeySize = 14; -constexpr uint8_t kAdvertisementVersion = 0; -constexpr uint8_t kVersionBitmask = 0b111; -constexpr uint8_t kDeviceTypeBitmask = 0b111; -constexpr uint8_t kVisibilityBitmask = 0b1; -constexpr uint8_t kTlvMinLength = 2; -constexpr uint8_t kVendorIdLength = 1; - -enum class TlvTypes : uint8_t { - kUnknown = 0, - kQrCode = 1, - kVendorId = 2, -}; - -uint8_t EncodeHeaderByte(bool has_device_name, ShareTargetType device_type) { - uint8_t version = static_cast((kAdvertisementVersion & kVersionBitmask) << 5); - uint8_t visibility = static_cast(((has_device_name ? 0 : 1) & kVisibilityBitmask) << 4); - uint8_t type = static_cast((static_cast(device_type) & kDeviceTypeBitmask) << 1); - return static_cast(version | visibility | type); -} - -bool ShouldIncludeDeviceName(const std::optional& device_name) { - return device_name.has_value() && !device_name->empty(); -} - -TransferMetadata::Status StatusFromPayloadStatus( - connections::PayloadProgressInfo::Status status) { - switch (status) { - case connections::PayloadProgressInfo::Status::kInProgress: - return TransferMetadata::Status::kInProgress; - case connections::PayloadProgressInfo::Status::kSuccess: - return TransferMetadata::Status::kComplete; - case connections::PayloadProgressInfo::Status::kFailure: - return TransferMetadata::Status::kFailed; - case connections::PayloadProgressInfo::Status::kCanceled: - return TransferMetadata::Status::kCancelled; - } - return TransferMetadata::Status::kUnknown; -} - -using Frame = nearby::sharing::service::proto::Frame; -using V1Frame = nearby::sharing::service::proto::V1Frame; -using IntroductionFrame = nearby::sharing::service::proto::IntroductionFrame; -using ConnectionResponseFrame = - nearby::sharing::service::proto::ConnectionResponseFrame; -using PairedKeyEncryptionFrame = - nearby::sharing::service::proto::PairedKeyEncryptionFrame; -using PairedKeyResultFrame = nearby::sharing::service::proto::PairedKeyResultFrame; - -constexpr size_t kPairedKeySignedDataSize = 72; -constexpr size_t kPairedKeySecretIdHashSize = 6; - -bool IsControlFrameType(V1Frame::FrameType type) { - switch (type) { - case V1Frame::INTRODUCTION: - case V1Frame::RESPONSE: - case V1Frame::PAIRED_KEY_ENCRYPTION: - case V1Frame::PAIRED_KEY_RESULT: - case V1Frame::CANCEL: - return true; - default: - return false; - } -} - -std::string MediumToString(connections::Medium medium) { - return ::location::nearby::proto::connections::Medium_Name(medium); -} - -bool TryParseControlFrame(const connections::Payload& payload, Frame* frame) { - if (!frame || payload.GetType() != connections::PayloadType::kBytes) { - return false; - } - std::string bytes = payload.AsBytes().string_data(); - if (!frame->ParseFromString(bytes) || !frame->has_v1() || - frame->version() != Frame::V1 || !frame->v1().has_type()) { - return false; - } - return IsControlFrameType(frame->v1().type()); -} - -bool SendFramePayload(connections::Core* core, const std::string& endpoint_id, - auto& transfer_state, const Frame& frame) { - if (core == nullptr) { - return false; - } - - std::string serialized; - if (!frame.SerializeToString(&serialized)) { - LOG(ERROR) << "Failed to serialize protocol frame."; - return false; - } - - connections::Payload payload{nearby::ByteArray(serialized)}; - transfer_state.control_payload_ids.insert(payload.GetId()); - std::vector endpoints{endpoint_id}; - core->SendPayload(endpoints, std::move(payload), [](connections::Status) {}); - return true; -} - -Frame BuildPairedKeyEncryptionFrame() { - Frame frame; - frame.set_version(Frame::V1); - V1Frame* v1_frame = frame.mutable_v1(); - v1_frame->set_type(V1Frame::PAIRED_KEY_ENCRYPTION); - PairedKeyEncryptionFrame* encryption_frame = - v1_frame->mutable_paired_key_encryption(); - std::vector secret_hash = GenerateRandomBytes(kPairedKeySecretIdHashSize); - std::vector signed_data = GenerateRandomBytes(kPairedKeySignedDataSize); - encryption_frame->set_secret_id_hash(secret_hash.data(), secret_hash.size()); - encryption_frame->set_signed_data(signed_data.data(), signed_data.size()); - return frame; -} - -Frame BuildPairedKeyResultFrame(PairedKeyResultFrame::Status status) { - Frame frame; - frame.set_version(Frame::V1); - V1Frame* v1_frame = frame.mutable_v1(); - v1_frame->set_type(V1Frame::PAIRED_KEY_RESULT); - PairedKeyResultFrame* result_frame = v1_frame->mutable_paired_key_result(); - result_frame->set_status(status); - result_frame->set_os_type( - location::nearby::proto::sharing::OSType::UNKNOWN_OS_TYPE); - return frame; -} - -Frame BuildConnectionResponseFrame(ConnectionResponseFrame::Status status) { - Frame frame; - frame.set_version(Frame::V1); - V1Frame* v1_frame = frame.mutable_v1(); - v1_frame->set_type(V1Frame::RESPONSE); - v1_frame->mutable_connection_response()->set_status(status); - return frame; -} - -bool PrepareOutgoingIntroductionAndPayloads(auto& transfer_state, - IntroductionFrame* introduction) { - if (introduction == nullptr) { - return false; - } - - transfer_state.pending_outgoing_payloads.clear(); - transfer_state.attachment_payload_ids.clear(); - transfer_state.completed_attachment_payload_ids.clear(); - transfer_state.expected_attachment_payload_count = 0; - introduction->set_start_transfer(true); - - AttachmentContainer& attachments = transfer_state.attachments; - for (int i = 0; i < attachments.GetFileAttachments().size(); ++i) { - FileAttachment& file = attachments.GetMutableFileAttachment(i); - if (!file.file_path().has_value()) { - LOG(WARNING) << "Outgoing file attachment missing path: " - << std::string(file.file_name()); - return false; - } - std::optional file_size = Files::GetFileSize(*file.file_path()); - if (file_size.has_value()) { - if (*file_size > - static_cast(std::numeric_limits::max())) { - LOG(WARNING) << "Outgoing file attachment size overflow: " - << std::string(file.file_name()); - return false; - } - file.set_size(static_cast(*file_size)); - } - if (file.size() <= 0) { - LOG(WARNING) << "Outgoing file attachment has invalid size: " - << std::string(file.file_name()) << " size=" << file.size(); - return false; - } - int64_t payload_id = connections::Payload::GenerateId(); - auto* metadata = introduction->add_file_metadata(); - metadata->set_id(file.id()); - metadata->set_name(std::string(file.file_name())); - metadata->set_type(file.type()); - metadata->set_payload_id(payload_id); - metadata->set_size(file.size()); - metadata->set_mime_type(std::string(file.mime_type())); - metadata->set_parent_folder(std::string(file.parent_folder())); - - nearby::InputFile input_file(file.file_path()->ToString()); - transfer_state.pending_outgoing_payloads.emplace_back( - payload_id, std::string(file.parent_folder()), - std::string(file.file_name()), std::move(input_file)); - transfer_state.attachment_payload_ids.insert(payload_id); - } - - for (const auto& text : attachments.GetTextAttachments()) { - int64_t payload_id = connections::Payload::GenerateId(); - auto* metadata = introduction->add_text_metadata(); - metadata->set_id(text.id()); - metadata->set_text_title(std::string(text.text_title())); - metadata->set_type(text.type()); - metadata->set_payload_id(payload_id); - metadata->set_size(text.size()); - - std::string body = std::string(text.text_body()); - transfer_state.pending_outgoing_payloads.emplace_back( - payload_id, nearby::ByteArray(body)); - transfer_state.attachment_payload_ids.insert(payload_id); - } - - transfer_state.expected_attachment_payload_count = - transfer_state.attachment_payload_ids.size(); - return true; -} - -void PopulateIncomingAttachmentsFromIntroduction( - auto& transfer_state, const IntroductionFrame& introduction) { - AttachmentContainer::Builder builder; - builder.ReserveAttachmentsCount( - introduction.text_metadata_size(), introduction.file_metadata_size(), - introduction.wifi_credentials_metadata_size()); - - transfer_state.text_attachment_id_by_payload_id.clear(); - transfer_state.file_attachment_id_by_payload_id.clear(); - transfer_state.attachment_payload_ids.clear(); - transfer_state.completed_attachment_payload_ids.clear(); - transfer_state.expected_attachment_payload_count = 0; - - for (const auto& file : introduction.file_metadata()) { - builder.AddFileAttachment(FileAttachment( - file.id(), file.size(), file.name(), file.mime_type(), file.type(), - file.parent_folder())); - transfer_state.file_attachment_id_by_payload_id[file.payload_id()] = - file.id(); - transfer_state.attachment_payload_ids.insert(file.payload_id()); - } - - for (const auto& text : introduction.text_metadata()) { - builder.AddTextAttachment(TextAttachment( - text.id(), text.type(), text.text_title(), text.size())); - transfer_state.text_attachment_id_by_payload_id[text.payload_id()] = - text.id(); - transfer_state.attachment_payload_ids.insert(text.payload_id()); - } - - transfer_state.expected_attachment_payload_count = - transfer_state.attachment_payload_ids.size(); - std::unique_ptr incoming = builder.Build(); - transfer_state.attachments = std::move(*incoming); -} - -void UpdateIncomingAttachmentPayload(auto& transfer_state, - connections::Payload& payload) { - if (payload.GetType() == connections::PayloadType::kBytes) { - auto text_it = transfer_state.text_attachment_id_by_payload_id.find( - payload.GetId()); - if (text_it == transfer_state.text_attachment_id_by_payload_id.end()) { - return; - } - - std::string body = payload.AsBytes().string_data(); - auto& texts = transfer_state.attachments.GetTextAttachments(); - for (int i = 0; i < texts.size(); ++i) { - if (texts[i].id() == text_it->second) { - transfer_state.attachments.GetMutableTextAttachment(i).set_text_body( - body); - return; - } - } - return; - } - - if (payload.GetType() != connections::PayloadType::kFile) { - return; - } - auto file_it = - transfer_state.file_attachment_id_by_payload_id.find(payload.GetId()); - if (file_it == transfer_state.file_attachment_id_by_payload_id.end()) { - return; - } - nearby::InputFile* input_file = payload.AsFile(); - if (input_file == nullptr) { - return; - } - - auto& files = transfer_state.attachments.GetFileAttachments(); - for (int i = 0; i < files.size(); ++i) { - if (files[i].id() == file_it->second) { - transfer_state.attachments.GetMutableFileAttachment(i).set_file_path( - nearby::FilePath(input_file->GetFilePath())); - return; - } - } -} - -} // namespace - -NearbySharingServiceLinux::NearbySharingServiceLinux() - : device_info_(::nearby::api::ImplementationPlatform::CreateDeviceInfo()), - router_(std::make_unique()), - core_(std::make_unique(router_.get())) { - if (device_info_) { - auto name = device_info_->GetOsDeviceName(); - if (name.has_value()) { - device_name_override_ = *name; - } - } -} - -NearbySharingServiceLinux::NearbySharingServiceLinux( - std::string device_name_override) - : device_name_override_(std::move(device_name_override)), - device_info_(::nearby::api::ImplementationPlatform::CreateDeviceInfo()), - router_(std::make_unique()), - core_(std::make_unique(router_.get())) {} - -NearbySharingServiceLinux::~NearbySharingServiceLinux() = default; - -void NearbySharingServiceLinux::AddObserver(Observer* observer) { - if (!observer) { - return; - } - observers_.insert(observer); -} - -void NearbySharingServiceLinux::RemoveObserver(Observer* observer) { - observers_.erase(observer); -} - -void NearbySharingServiceLinux::Shutdown( - std::function - status_codes_callback) { - StopDiscovery(); - StopAdvertising(); - endpoint_to_target_.clear(); - target_id_to_endpoint_.clear(); - active_transfers_.clear(); - is_transferring_ = false; - std::move(status_codes_callback)(StatusCodes::kOk); -} - -void NearbySharingServiceLinux::RegisterSendSurface( - TransferUpdateCallback* transfer_callback, - ShareTargetDiscoveredCallback* discovery_callback, SendSurfaceState state, - Advertisement::BlockedVendorId blocked_vendor_id, - bool disable_wifi_hotspot, - std::function - status_codes_callback) { - static_cast(blocked_vendor_id); - if (!transfer_callback) { - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); - return; - } - - send_surfaces_[transfer_callback] = SendSurface{ - .discovery_callback = discovery_callback, - .state = state, - .disable_wifi_hotspot = disable_wifi_hotspot, - }; - - StartDiscoveryIfNeeded(); - std::move(status_codes_callback)(StatusCodes::kOk); -} - -void NearbySharingServiceLinux::UnregisterSendSurface( - TransferUpdateCallback* transfer_callback, - std::function - status_codes_callback) { - if (!transfer_callback) { - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); - return; - } - - send_surfaces_.erase(transfer_callback); - if (send_surfaces_.empty()) { - StopDiscovery(); - } - - std::move(status_codes_callback)(StatusCodes::kOk); -} - -void NearbySharingServiceLinux::RegisterReceiveSurface( - TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state, - Advertisement::BlockedVendorId vendor_id, - std::function - status_codes_callback) { - if (!transfer_callback) { - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); - return; - } - - receive_surfaces_[transfer_callback] = ReceiveSurface{ - .state = state, - .vendor_id = vendor_id, - }; - - StartAdvertisingIfNeeded(); - std::move(status_codes_callback)(StatusCodes::kOk); -} - -void NearbySharingServiceLinux::UnregisterReceiveSurface( - TransferUpdateCallback* transfer_callback, - std::function - status_codes_callback) { - if (!transfer_callback) { - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); - return; - } - - receive_surfaces_.erase(transfer_callback); - if (receive_surfaces_.empty()) { - StopAdvertising(); - } else { - StartAdvertisingIfNeeded(); - } - - std::move(status_codes_callback)(StatusCodes::kOk); -} - -void NearbySharingServiceLinux::ClearForegroundReceiveSurfaces( - std::function - status_codes_callback) { - for (auto it = receive_surfaces_.begin(); it != receive_surfaces_.end();) { - if (it->second.state == ReceiveSurfaceState::kForeground) { - it = receive_surfaces_.erase(it); - } else { - ++it; - } - } - - if (receive_surfaces_.empty()) { - StopAdvertising(); - } else { - StartAdvertisingIfNeeded(); - } - - std::move(status_codes_callback)(StatusCodes::kOk); -} - -bool NearbySharingServiceLinux::IsTransferring() const { - return is_transferring_; -} - -bool NearbySharingServiceLinux::IsScanning() const { return is_scanning_; } - -bool NearbySharingServiceLinux::IsBluetoothPresent() const { - return bluetooth_adapter_.IsValid(); -} - -bool NearbySharingServiceLinux::IsBluetoothPowered() const { - return bluetooth_adapter_.IsValid() && bluetooth_adapter_.IsEnabled(); -} - -bool NearbySharingServiceLinux::IsExtendedAdvertisingSupported() const { - return true; -} - -bool NearbySharingServiceLinux::IsLanConnected() const { return false; } - -std::string NearbySharingServiceLinux::GenerateQrCodeUrl() const { - // Generate ECDSA P-256 key pair - auto ec_key = nearby::crypto::ECPrivateKey::Create(); - if (!ec_key) { - LOG(ERROR) << "Failed to generate EC key for QR code"; - return ""; - } - - // Get the EC_KEY from EVP_PKEY - EC_KEY* raw_ec_key = EVP_PKEY_get0_EC_KEY(ec_key->key()); - if (!raw_ec_key) { - LOG(ERROR) << "Failed to get EC_KEY from EVP_PKEY"; - return ""; - } - - const EC_GROUP* group = EC_KEY_get0_group(raw_ec_key); - const EC_POINT* pub_key = EC_KEY_get0_public_key(raw_ec_key); - if (!group || !pub_key) { - LOG(ERROR) << "Failed to get EC group or public key"; - return ""; - } - - // Get the X and Y coordinates - BIGNUM* x = BN_new(); - BIGNUM* y = BN_new(); - if (!x || !y) { - BN_free(x); - BN_free(y); - LOG(ERROR) << "Failed to allocate BIGNUMs"; - return ""; - } - - if (!EC_POINT_get_affine_coordinates_GFp(group, pub_key, x, y, nullptr)) { - BN_free(x); - BN_free(y); - LOG(ERROR) << "Failed to get affine coordinates"; - return ""; - } - - // Convert X coordinate to bytes (32 bytes for P-256) - std::vector x_bytes(32, 0); - int x_len = BN_num_bytes(x); - if (x_len > 32) { - BN_free(x); - BN_free(y); - LOG(ERROR) << "X coordinate too large"; - return ""; - } - - // Pad with leading zeros if needed - int offset = 32 - x_len; - BN_bn2bin(x, x_bytes.data() + offset); - - // Determine prefix byte based on Y coordinate parity - // 0x02 if Y is even, 0x03 if Y is odd - uint8_t prefix = BN_is_odd(y) ? 0x03 : 0x02; - - BN_free(x); - BN_free(y); - - // Build the key data: [version (2 bytes), prefix (1 byte), X coordinate (32 bytes)] - std::vector key_data; - key_data.reserve(35); // 2 + 1 + 32 - key_data.push_back(0x00); // Version byte 1 - key_data.push_back(0x00); // Version byte 2 - key_data.push_back(prefix); // Prefix byte (0x02 or 0x03) - key_data.insert(key_data.end(), x_bytes.begin(), x_bytes.end()); // X coordinate - - // Base64url encode - std::string encoded; - absl::WebSafeBase64Escape( - std::string(reinterpret_cast(key_data.data()), key_data.size()), - &encoded); - - // Build the final URL - return "https://quickshare.google/qrcode#key=" + encoded; -} - -std::string NearbySharingServiceLinux::GetQrCodeUrl() const { - // Generate the URL once and cache it - if (qr_code_url_.empty()) { - qr_code_url_ = GenerateQrCodeUrl(); - } - return qr_code_url_; -} - -void NearbySharingServiceLinux::SendAttachments( - int64_t share_target_id, - std::unique_ptr - attachment_container, - std::function - status_codes_callback) { - auto endpoint_id = GetEndpointIdForTarget(share_target_id); - if (!endpoint_id.has_value() || !attachment_container || - !attachment_container->HasAttachments()) { - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); - return; - } - - TransferUpdateCallback* callback = PickSendTransferCallback(); - if (!callback) { - std::move(status_codes_callback)(StatusCodes::kOutOfOrderApiCall); - return; - } - - TransferState transfer_state; - transfer_state.attachments = std::move(*attachment_container); - transfer_state.callback = callback; - transfer_state.is_incoming = false; - active_transfers_.erase(*endpoint_id); - auto transfer_insert_result = - active_transfers_.emplace(*endpoint_id, std::move(transfer_state)); - auto transfer_it = transfer_insert_result.first; - - TransferMetadata metadata = - TransferMetadataBuilder().set_status(TransferMetadata::Status::kConnecting) - .set_progress(0) - .set_total_attachments_count( - attachment_container->GetAttachmentCount()) - .build(); - if (auto share_target = GetShareTarget(*endpoint_id)) { - NotifyTransferUpdate(*share_target, transfer_it->second, metadata); - } - - connections::ConnectionOptions options; - options.strategy = kStrategy; - options.allowed.SetAll(true); - - std::optional device_name = - device_name_override_.empty() - ? std::optional(std::nullopt) - : std::optional(device_name_override_); - if (!device_name.has_value() && device_info_) { - auto name = device_info_->GetOsDeviceName(); - if (name.has_value()) { - device_name = *name; - } - } - - ShareTargetType device_type = ShareTargetType::kUnknown; - if (device_info_) { - device_type = - static_cast(device_info_->GetDeviceType()); - } - - std::vector endpoint_info = - BuildAdvertisement(device_name, device_type, - static_cast( - Advertisement::BlockedVendorId::kNone)); - connections::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& id, - const connections::ConnectionResponseInfo& info) { - HandleOutgoingConnectionInitiated(id, info); - }; - request_info.listener.accepted_cb = [this](const std::string& id) { - HandleConnectionAccepted(id, /*is_incoming=*/false); - }; - request_info.listener.rejected_cb = - [this](const std::string& id, connections::Status status) { - HandleConnectionRejected(id, status, /*is_incoming=*/false); - }; - request_info.listener.disconnected_cb = [this](const std::string& id) { - HandleConnectionDisconnected(id); - }; - request_info.listener.bandwidth_changed_cb = - [this](const std::string& id, connections::Medium medium) { - auto transfer_it = active_transfers_.find(id); - if (transfer_it != active_transfers_.end()) { - transfer_it->second.current_medium = medium; - } - LOG(INFO) << "Transfer medium changed endpoint=" << id - << " medium=" << MediumToString(medium); - }; - - core_->RequestConnection(*endpoint_id, request_info, options, - [this, cb = std::move(status_codes_callback)]( - connections::Status status) mutable { - cb(StatusFromConnections(status)); - }); -} - -void NearbySharingServiceLinux::Accept( - int64_t share_target_id, - std::function - status_codes_callback) { - auto endpoint_id = GetEndpointIdForTarget(share_target_id); - if (!endpoint_id.has_value()) { - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); - return; - } - - core_->AcceptConnection(*endpoint_id, MakePayloadListener(true), - [this, cb = std::move(status_codes_callback)]( - connections::Status status) mutable { - cb(StatusFromConnections(status)); - }); -} - -void NearbySharingServiceLinux::Reject( - int64_t share_target_id, - std::function - status_codes_callback) { - auto endpoint_id = GetEndpointIdForTarget(share_target_id); - if (!endpoint_id.has_value()) { - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); - return; - } - - core_->RejectConnection(*endpoint_id, - [this, cb = std::move(status_codes_callback)]( - connections::Status status) mutable { - cb(StatusFromConnections(status)); - }); -} - -void NearbySharingServiceLinux::Cancel( - int64_t share_target_id, - std::function - status_codes_callback) { - auto endpoint_id = GetEndpointIdForTarget(share_target_id); - if (!endpoint_id.has_value()) { - std::move(status_codes_callback)(StatusCodes::kInvalidArgument); - return; - } - - core_->DisconnectFromEndpoint( - *endpoint_id, - [this, cb = std::move(status_codes_callback)](connections::Status status) mutable { - cb(StatusFromConnections(status)); - }); -} - -void NearbySharingServiceLinux::SetVisibility( - proto::DeviceVisibility visibility, absl::Duration expiration, - absl::AnyInvocable callback) { - static_cast(visibility); - static_cast(expiration); - std::move(callback)(StatusCodes::kOk); -} - -std::string NearbySharingServiceLinux::Dump() const { - std::stringstream ss; - ss << "NearbySharingServiceLinux"; - ss << " advertising=" << (is_advertising_ ? "true" : "false"); - ss << " scanning=" << (is_scanning_ ? "true" : "false"); - ss << " transfers=" << active_transfers_.size(); - ss << " targets=" << endpoint_to_target_.size(); - return ss.str(); -} - -void NearbySharingServiceLinux::UpdateFilePathsInProgress( - bool update_file_paths) {} - -NearbyShareSettings* NearbySharingServiceLinux::GetSettings() { - return nullptr; -} - -NearbyShareLocalDeviceDataManager* -NearbySharingServiceLinux::GetLocalDeviceDataManager() { - return nullptr; -} - -NearbyShareContactManager* NearbySharingServiceLinux::GetContactManager() { - return nullptr; -} - -NearbyShareCertificateManager* -NearbySharingServiceLinux::GetCertificateManager() { - return nullptr; -} - -AccountManager* NearbySharingServiceLinux::GetAccountManager() { - return nullptr; -} - -Clock& NearbySharingServiceLinux::GetClock() { return clock_; } - -void NearbySharingServiceLinux::SetAlternateServiceUuidForDiscovery( - uint16_t alternate_service_uuid) { - alternate_service_uuid_ = alternate_service_uuid; - if (is_scanning_) { - StopDiscovery(); - StartDiscoveryIfNeeded(); - } -} - -void NearbySharingServiceLinux::StartAdvertisingIfNeeded() { - if (receive_surfaces_.empty()) { - StopAdvertising(); - return; - } - - bool has_foreground = false; - uint8_t vendor_id = 0; - for (const auto& [callback, surface] : receive_surfaces_) { - if (surface.state == ReceiveSurfaceState::kForeground) { - has_foreground = true; - vendor_id = static_cast(surface.vendor_id); - break; - } - } - - std::optional device_name = std::nullopt; - if (has_foreground) { - if (!device_name_override_.empty()) { - device_name = device_name_override_; - } else if (device_info_) { - auto name = device_info_->GetOsDeviceName(); - if (name.has_value()) { - device_name = *name; - } - } - } - - ShareTargetType device_type = ShareTargetType::kUnknown; - if (device_info_) { - device_type = - static_cast(device_info_->GetDeviceType()); - } - - if (is_advertising_ && has_foreground == last_advertise_with_name_ && - vendor_id == last_advertise_vendor_id_) { - return; - } - - if (is_advertising_) { - StopAdvertising(); - } - - std::vector endpoint_info = - BuildAdvertisement(device_name, device_type, vendor_id); - - connections::AdvertisingOptions options; - options.strategy = kStrategy; - options.allowed.SetAll(true); - options.use_stable_endpoint_id = has_foreground; - - connections::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& id, - const connections::ConnectionResponseInfo& info) { - HandleIncomingConnectionInitiated(id, info); - }; - request_info.listener.accepted_cb = [this](const std::string& id) { - HandleConnectionAccepted(id, /*is_incoming=*/true); - }; - request_info.listener.rejected_cb = - [this](const std::string& id, connections::Status status) { - HandleConnectionRejected(id, status, /*is_incoming=*/true); - }; - request_info.listener.disconnected_cb = [this](const std::string& id) { - HandleConnectionDisconnected(id); - }; - request_info.listener.bandwidth_changed_cb = - [this](const std::string& id, connections::Medium medium) { - auto transfer_it = active_transfers_.find(id); - if (transfer_it != active_transfers_.end()) { - transfer_it->second.current_medium = medium; - } - LOG(INFO) << "Transfer medium changed endpoint=" << id - << " medium=" << MediumToString(medium); - }; - - core_->StartAdvertising( - kServiceId, options, std::move(request_info), - [this, has_foreground, vendor_id](connections::Status status) { - is_advertising_ = status.Ok(); - if (is_advertising_) { - last_advertise_with_name_ = has_foreground; - last_advertise_vendor_id_ = vendor_id; - } - }); -} - -void NearbySharingServiceLinux::StopAdvertising() { - if (!is_advertising_) { - return; - } - is_advertising_ = false; - core_->StopAdvertising([](connections::Status status) { - static_cast(status); - }); -} - -void NearbySharingServiceLinux::StartDiscoveryIfNeeded() { - bool needs_scanning = false; - for (const auto& [callback, surface] : send_surfaces_) { - if (surface.state == SendSurfaceState::kForeground) { - needs_scanning = true; - break; - } - } - - if (!needs_scanning) { - StopDiscovery(); - return; - } - - if (is_scanning_) { - return; - } - - connections::DiscoveryOptions options; - options.strategy = kStrategy; - options.allowed.SetAll(true); - if (alternate_service_uuid_.has_value()) { - options.ble_options.alternate_uuid = *alternate_service_uuid_; - } - - connections::DiscoveryListener listener; - listener.endpoint_found_cb = - [this](const std::string& endpoint_id, const ByteArray& endpoint_info, - const std::string& service_id) { - static_cast(service_id); - std::string info_string = std::string(endpoint_info); - std::vector info_bytes(info_string.begin(), info_string.end()); - ParsedAdvertisement parsed; - if (auto parsed_opt = ParseAdvertisement(info_bytes)) { - parsed = *parsed_opt; - } - - ShareTarget target; - target.id = next_share_target_id_++; - if (parsed.device_name.has_value()) { - target.device_name = *parsed.device_name; - } else { - target.device_name = endpoint_id; - } - target.type = parsed.device_type; - target.is_incoming = false; - target.vendor_id = parsed.vendor_id; - - auto existing = endpoint_to_target_.find(endpoint_id); - if (existing == endpoint_to_target_.end()) { - endpoint_to_target_[endpoint_id] = target; - target_id_to_endpoint_[target.id] = endpoint_id; - NotifyShareTargetDiscovered(target); - } else { - target.id = existing->second.id; - endpoint_to_target_[endpoint_id] = target; - NotifyShareTargetUpdated(target); - } - }; - listener.endpoint_lost_cb = [this](const std::string& endpoint_id) { - auto it = endpoint_to_target_.find(endpoint_id); - if (it == endpoint_to_target_.end()) { - return; - } - ShareTarget target = it->second; - endpoint_to_target_.erase(it); - target_id_to_endpoint_.erase(target.id); - NotifyShareTargetLost(target); - }; - - core_->StartDiscovery( - kServiceId, options, std::move(listener), - [this](connections::Status status) { is_scanning_ = status.Ok(); }); -} - -void NearbySharingServiceLinux::StopDiscovery() { - if (!is_scanning_) { - return; - } - core_->StopDiscovery([this](connections::Status status) { - if (status.Ok()) { - is_scanning_ = false; - } - }); -} - -std::vector NearbySharingServiceLinux::BuildAdvertisement( - const std::optional& device_name, ShareTargetType device_type, - uint8_t vendor_id) const { - const bool has_device_name = ShouldIncludeDeviceName(device_name); - std::vector salt = GenerateRandomBytes(kAdvertisementSaltSize); - std::vector metadata_key = - GenerateRandomBytes(kAdvertisementMetadataKeySize); - - size_t size = 1 + salt.size() + metadata_key.size(); - if (has_device_name) { - size += 1 + device_name->size(); - } - if (vendor_id != 0) { - size += kTlvMinLength + kVendorIdLength; - } - - std::vector endpoint_info; - endpoint_info.reserve(size); - endpoint_info.push_back(EncodeHeaderByte(has_device_name, device_type)); - endpoint_info.insert(endpoint_info.end(), salt.begin(), salt.end()); - endpoint_info.insert(endpoint_info.end(), metadata_key.begin(), - metadata_key.end()); - - if (has_device_name) { - endpoint_info.push_back( - static_cast(device_name->size() & 0xff)); - endpoint_info.insert(endpoint_info.end(), device_name->begin(), - device_name->end()); - } - - if (vendor_id != 0) { - endpoint_info.push_back(static_cast(TlvTypes::kVendorId)); - endpoint_info.push_back(kVendorIdLength); - endpoint_info.push_back(vendor_id); - } - - return endpoint_info; -} - -std::optional -NearbySharingServiceLinux::ParseAdvertisement( - absl::Span endpoint_info) const { - ParsedAdvertisement parsed; - const size_t minimum_size = - 1 + kAdvertisementSaltSize + kAdvertisementMetadataKeySize; - if (endpoint_info.size() < minimum_size) { - return std::nullopt; - } - - size_t offset = 0; - uint8_t header = endpoint_info[offset++]; - bool has_device_name = ((header >> 4) & kVisibilityBitmask) == 0; - uint8_t type = (header >> 1) & kDeviceTypeBitmask; - if (type <= static_cast(ShareTargetType::kXR)) { - parsed.device_type = static_cast(type); - } else { - parsed.device_type = ShareTargetType::kUnknown; - } - - offset += kAdvertisementSaltSize + kAdvertisementMetadataKeySize; - if (has_device_name) { - if (offset >= endpoint_info.size()) { - return parsed; - } - uint8_t name_length = endpoint_info[offset++]; - if (name_length == 0 || offset + name_length > endpoint_info.size()) { - return parsed; - } - parsed.device_name = std::string( - reinterpret_cast(endpoint_info.data() + offset), - name_length); - offset += name_length; - } - - while (offset + kTlvMinLength <= endpoint_info.size()) { - uint8_t tlv_type = endpoint_info[offset++]; - uint8_t tlv_length = endpoint_info[offset++]; - if (offset + tlv_length > endpoint_info.size()) { - break; - } - if (tlv_type == static_cast(TlvTypes::kVendorId) && - tlv_length == kVendorIdLength) { - parsed.vendor_id = endpoint_info[offset]; - } - offset += tlv_length; - } - - return parsed; -} - -void NearbySharingServiceLinux::NotifyShareTargetDiscovered( - const ShareTarget& share_target) { - for (const auto& [transfer_callback, surface] : send_surfaces_) { - if (surface.state != SendSurfaceState::kForeground || - surface.discovery_callback == nullptr) { - continue; - } - surface.discovery_callback->OnShareTargetDiscovered(share_target); - } -} - -void NearbySharingServiceLinux::NotifyShareTargetUpdated( - const ShareTarget& share_target) { - for (const auto& [transfer_callback, surface] : send_surfaces_) { - if (surface.state != SendSurfaceState::kForeground || - surface.discovery_callback == nullptr) { - continue; - } - surface.discovery_callback->OnShareTargetUpdated(share_target); - } -} - -void NearbySharingServiceLinux::NotifyShareTargetLost( - const ShareTarget& share_target) { - for (const auto& [transfer_callback, surface] : send_surfaces_) { - if (surface.state != SendSurfaceState::kForeground || - surface.discovery_callback == nullptr) { - continue; - } - surface.discovery_callback->OnShareTargetLost(share_target); - } -} - -void NearbySharingServiceLinux::NotifyTransferUpdate( - const ShareTarget& share_target, const TransferState& transfer_state, - const TransferMetadata& metadata) { - if (!transfer_state.callback) { - return; - } - transfer_state.callback->OnTransferUpdate(share_target, - transfer_state.attachments, - metadata); -} - -TransferUpdateCallback* NearbySharingServiceLinux::PickSendTransferCallback() - const { - if (send_surfaces_.empty()) { - return nullptr; - } - return send_surfaces_.begin()->first; -} - -TransferUpdateCallback* NearbySharingServiceLinux::PickReceiveTransferCallback() - const { - if (receive_surfaces_.empty()) { - return nullptr; - } - return receive_surfaces_.begin()->first; -} - -std::optional NearbySharingServiceLinux::GetEndpointIdForTarget( - int64_t share_target_id) const { - auto it = target_id_to_endpoint_.find(share_target_id); - if (it == target_id_to_endpoint_.end()) { - return std::nullopt; - } - return it->second; -} - -std::optional NearbySharingServiceLinux::GetShareTarget( - absl::string_view endpoint_id) const { - auto it = endpoint_to_target_.find(std::string(endpoint_id)); - if (it == endpoint_to_target_.end()) { - return std::nullopt; - } - return it->second; -} - -void NearbySharingServiceLinux::HandleIncomingConnectionInitiated( - const std::string& endpoint_id, - const connections::ConnectionResponseInfo& info) { - static_cast(info); - std::vector info_bytes(info.remote_endpoint_info.begin(), - info.remote_endpoint_info.end()); - ParsedAdvertisement parsed; - if (auto parsed_opt = ParseAdvertisement(info_bytes)) { - parsed = *parsed_opt; - } - - ShareTarget target; - target.id = next_share_target_id_++; - target.device_name = parsed.device_name.value_or(endpoint_id); - target.type = parsed.device_type; - target.is_incoming = true; - target.vendor_id = parsed.vendor_id; - - auto existing = endpoint_to_target_.find(endpoint_id); - if (existing == endpoint_to_target_.end()) { - endpoint_to_target_[endpoint_id] = target; - target_id_to_endpoint_[target.id] = endpoint_id; - } else { - target.id = existing->second.id; - endpoint_to_target_[endpoint_id] = target; - } - - TransferState transfer_state; - transfer_state.attachments = AttachmentContainer(); - transfer_state.callback = PickReceiveTransferCallback(); - transfer_state.is_incoming = true; - active_transfers_.erase(endpoint_id); - auto transfer_insert_result = - active_transfers_.emplace(endpoint_id, std::move(transfer_state)); - auto transfer_it = transfer_insert_result.first; - - TransferMetadata metadata = TransferMetadataBuilder() - .set_status(TransferMetadata::Status::kAwaitingLocalConfirmation) - .set_progress(0) - .build(); - NotifyTransferUpdate(target, transfer_it->second, metadata); -} - -void NearbySharingServiceLinux::HandleOutgoingConnectionInitiated( - const std::string& endpoint_id, - const connections::ConnectionResponseInfo& info) { - static_cast(info); - core_->AcceptConnection(endpoint_id, MakePayloadListener(false), - [this, endpoint_id](connections::Status status) { - if (!status.Ok()) { - HandleConnectionRejected(endpoint_id, status, - /*is_incoming=*/false); - } - }); - - auto share_target = GetShareTarget(endpoint_id); - auto transfer_it = active_transfers_.find(endpoint_id); - if (share_target && transfer_it != active_transfers_.end()) { - TransferMetadata metadata = - TransferMetadataBuilder() - .set_status(TransferMetadata::Status::kAwaitingRemoteAcceptance) - .set_progress(0) - .build(); - NotifyTransferUpdate(*share_target, transfer_it->second, metadata); - } -} - -void NearbySharingServiceLinux::HandleConnectionAccepted( - const std::string& endpoint_id, bool is_incoming) { - auto transfer_it = active_transfers_.find(endpoint_id); - if (transfer_it == active_transfers_.end()) { - return; - } - - TransferState& transfer_state = transfer_it->second; - auto share_target = GetShareTarget(endpoint_id); - if (share_target) { - TransferMetadata::Status status = is_incoming - ? TransferMetadata::Status::kInProgress - : TransferMetadata::Status::kAwaitingRemoteAcceptance; - TransferMetadata metadata = - TransferMetadataBuilder() - .set_status(status) - .set_progress(0) - .set_total_attachments_count( - transfer_state.attachments.GetAttachmentCount()) - .build(); - NotifyTransferUpdate(*share_target, transfer_state, metadata); - } - - // Start minimal Nearby Share frame exchange: PAIRED_KEY_ENCRYPTION. - if (!transfer_state.paired_key_encryption_sent) { - Frame frame = BuildPairedKeyEncryptionFrame(); - if (SendFramePayload(core_.get(), endpoint_id, transfer_state, frame)) { - transfer_state.paired_key_encryption_sent = true; - } - } - - is_transferring_ = true; -} - -void NearbySharingServiceLinux::HandleConnectionRejected( - const std::string& endpoint_id, connections::Status status, - bool is_incoming) { - static_cast(status); - static_cast(is_incoming); - auto transfer_it = active_transfers_.find(endpoint_id); - if (transfer_it == active_transfers_.end()) { - return; - } - auto share_target = GetShareTarget(endpoint_id); - if (share_target) { - TransferMetadata metadata = TransferMetadataBuilder() - .set_status(TransferMetadata::Status::kRejected) - .set_progress(0) - .build(); - NotifyTransferUpdate(*share_target, transfer_it->second, metadata); - } - active_transfers_.erase(transfer_it); - is_transferring_ = false; -} - -void NearbySharingServiceLinux::HandleConnectionDisconnected( - const std::string& endpoint_id) { - active_transfers_.erase(endpoint_id); - if (active_transfers_.empty()) { - is_transferring_ = false; - } -} - -connections::PayloadListener NearbySharingServiceLinux::MakePayloadListener( - bool is_incoming) { - static_cast(is_incoming); - connections::PayloadListener listener; - listener.payload_cb = - [this](absl::string_view endpoint_id, connections::Payload payload) { - auto transfer_it = active_transfers_.find(std::string(endpoint_id)); - if (transfer_it == active_transfers_.end()) { - return; - } - auto share_target = GetShareTarget(endpoint_id); - if (!share_target) { - return; - } - - TransferState& transfer_state = transfer_it->second; - - Frame frame; - if (TryParseControlFrame(payload, &frame)) { - transfer_state.control_payload_ids.insert(payload.GetId()); - const V1Frame& v1 = frame.v1(); - switch (v1.type()) { - case V1Frame::PAIRED_KEY_ENCRYPTION: { - transfer_state.paired_key_encryption_received = true; - if (!transfer_state.paired_key_encryption_sent) { - Frame local_encryption = BuildPairedKeyEncryptionFrame(); - if (SendFramePayload(core_.get(), std::string(endpoint_id), - transfer_state, local_encryption)) { - transfer_state.paired_key_encryption_sent = true; - } - } - if (!transfer_state.paired_key_result_sent) { - Frame result = BuildPairedKeyResultFrame( - PairedKeyResultFrame::UNABLE); - if (SendFramePayload(core_.get(), std::string(endpoint_id), - transfer_state, result)) { - transfer_state.paired_key_result_sent = true; - } - } - break; - } - case V1Frame::PAIRED_KEY_RESULT: - transfer_state.paired_key_result_received = true; - break; - case V1Frame::INTRODUCTION: { - transfer_state.introduction_received = true; - if (transfer_state.is_incoming && v1.has_introduction()) { - PopulateIncomingAttachmentsFromIntroduction( - transfer_state, v1.introduction()); - if (!transfer_state.connection_response_sent) { - Frame response = - BuildConnectionResponseFrame(ConnectionResponseFrame::ACCEPT); - if (SendFramePayload(core_.get(), std::string(endpoint_id), - transfer_state, response)) { - transfer_state.connection_response_sent = true; - transfer_state.connection_response_accepted = true; - } - } - TransferMetadata metadata = - TransferMetadataBuilder() - .set_status(TransferMetadata::Status::kInProgress) - .set_progress(0) - .set_total_attachments_count( - transfer_state.attachments.GetAttachmentCount()) - .build(); - NotifyTransferUpdate(*share_target, transfer_state, metadata); - } - break; - } - case V1Frame::RESPONSE: { - if (!transfer_state.is_incoming && v1.has_connection_response()) { - transfer_state.connection_response_received = true; - transfer_state.connection_response_accepted = - v1.connection_response().status() == - ConnectionResponseFrame::ACCEPT; - if (!transfer_state.connection_response_accepted) { - TransferMetadata::Status rejected_status = - TransferMetadata::Status::kRejected; - TransferMetadata metadata = - TransferMetadataBuilder() - .set_status(rejected_status) - .set_progress(0) - .build(); - NotifyTransferUpdate(*share_target, transfer_state, metadata); - active_transfers_.erase(transfer_it); - if (active_transfers_.empty()) { - is_transferring_ = false; - } - return; - } - } - break; - } - case V1Frame::CANCEL: { - TransferMetadata metadata = - TransferMetadataBuilder() - .set_status(TransferMetadata::Status::kCancelled) - .set_progress(0) - .build(); - NotifyTransferUpdate(*share_target, transfer_state, metadata); - active_transfers_.erase(transfer_it); - if (active_transfers_.empty()) { - is_transferring_ = false; - } - return; - } - default: - break; - } - - // Sender-side progression: - if (!transfer_state.is_incoming && - transfer_state.paired_key_encryption_sent && - transfer_state.paired_key_encryption_received && - transfer_state.paired_key_result_sent && - transfer_state.paired_key_result_received && - !transfer_state.introduction_sent) { - Frame introduction_frame; - introduction_frame.set_version(Frame::V1); - V1Frame* out_v1 = introduction_frame.mutable_v1(); - out_v1->set_type(V1Frame::INTRODUCTION); - if (!PrepareOutgoingIntroductionAndPayloads( - transfer_state, out_v1->mutable_introduction())) { - LOG(ERROR) << "Failed to prepare outgoing introduction frame."; - TransferMetadata metadata = - TransferMetadataBuilder() - .set_status(TransferMetadata::Status::kFailed) - .set_progress(0) - .build(); - NotifyTransferUpdate(*share_target, transfer_state, metadata); - core_->DisconnectFromEndpoint(std::string(endpoint_id), - [](connections::Status) {}); - active_transfers_.erase(transfer_it); - if (active_transfers_.empty()) { - is_transferring_ = false; - } - return; - } - if (SendFramePayload(core_.get(), std::string(endpoint_id), - transfer_state, introduction_frame)) { - transfer_state.introduction_sent = true; - } else { - LOG(ERROR) << "Failed to send outgoing introduction frame."; - TransferMetadata metadata = - TransferMetadataBuilder() - .set_status(TransferMetadata::Status::kFailed) - .set_progress(0) - .build(); - NotifyTransferUpdate(*share_target, transfer_state, metadata); - core_->DisconnectFromEndpoint(std::string(endpoint_id), - [](connections::Status) {}); - active_transfers_.erase(transfer_it); - if (active_transfers_.empty()) { - is_transferring_ = false; - } - return; - } - } - - if (!transfer_state.is_incoming && transfer_state.introduction_sent && - transfer_state.connection_response_received && - transfer_state.connection_response_accepted && - !transfer_state.attachment_payloads_sent) { - transfer_state.attachment_payloads_sent = true; - std::vector endpoints{std::string(endpoint_id)}; - for (auto& data_payload : transfer_state.pending_outgoing_payloads) { - transfer_state.attachment_payload_ids.insert(data_payload.GetId()); - core_->SendPayload(endpoints, std::move(data_payload), - [](connections::Status) {}); - } - transfer_state.pending_outgoing_payloads.clear(); - } - return; - } - - // Non-control payloads are attachment payloads. - UpdateIncomingAttachmentPayload(transfer_state, payload); - }; - - listener.payload_progress_cb = - [this](absl::string_view endpoint_id, - const connections::PayloadProgressInfo& info) { - std::string endpoint_id_string(endpoint_id); - auto transfer_it = active_transfers_.find(endpoint_id_string); - if (transfer_it == active_transfers_.end()) { - return; - } - auto share_target = GetShareTarget(endpoint_id); - if (!share_target) { - return; - } - - TransferState& transfer_state = transfer_it->second; - if (transfer_state.control_payload_ids.contains(info.payload_id)) { - return; - } - if (transfer_state.expected_attachment_payload_count == 0) { - return; - } - if (!transfer_state.attachment_payload_ids.contains(info.payload_id)) { - return; - } - - size_t completed = transfer_state.completed_attachment_payload_ids.size(); - float progress = static_cast(completed) / - static_cast( - transfer_state.expected_attachment_payload_count); - TransferMetadata::Status status = TransferMetadata::Status::kInProgress; - - if (info.status == connections::PayloadProgressInfo::Status::kInProgress) { - if (info.total_bytes > 0) { - float payload_progress = static_cast(info.bytes_transferred) / - static_cast(info.total_bytes); - progress = - (static_cast(completed) + payload_progress) / - static_cast(transfer_state.expected_attachment_payload_count); - } - } else if (info.status == - connections::PayloadProgressInfo::Status::kSuccess) { - transfer_state.completed_attachment_payload_ids.insert(info.payload_id); - completed = transfer_state.completed_attachment_payload_ids.size(); - progress = static_cast(completed) / - static_cast( - transfer_state.expected_attachment_payload_count); - status = completed >= transfer_state.expected_attachment_payload_count - ? TransferMetadata::Status::kComplete - : TransferMetadata::Status::kInProgress; - } else { - status = StatusFromPayloadStatus(info.status); - } - - if (progress + 0.0001f < transfer_state.max_reported_progress) { - LOG(WARNING) << "Transfer progress regressed target=" - << share_target->id << " endpoint=" << endpoint_id_string - << " medium=" - << MediumToString(transfer_state.current_medium) - << " payload_id=" << info.payload_id - << " status=" << static_cast(info.status) - << " bytes=" << info.bytes_transferred << "/" - << info.total_bytes << " completed=" << completed << "/" - << transfer_state.expected_attachment_payload_count - << " progress=" << progress << " max_seen=" - << transfer_state.max_reported_progress; - } else if (progress > transfer_state.max_reported_progress) { - transfer_state.max_reported_progress = progress; - } - - TransferMetadata metadata = - TransferMetadataBuilder() - .set_status(status) - .set_progress(std::min(progress, 1.0f)) - .set_transferred_bytes(info.bytes_transferred) - .set_total_attachments_count( - static_cast( - transfer_state.expected_attachment_payload_count)) - .build(); - NotifyTransferUpdate(*share_target, transfer_state, metadata); - - if (TransferMetadata::IsFinalStatus(metadata.status())) { - if (metadata.status() == TransferMetadata::Status::kComplete) { - core_->DisconnectFromEndpoint(endpoint_id_string, - [](connections::Status) {}); - } - active_transfers_.erase(transfer_it); - if (active_transfers_.empty()) { - is_transferring_ = false; - } - } - }; - return listener; -} - -NearbySharingService::StatusCodes NearbySharingServiceLinux::StatusFromConnections( - connections::Status status) const { - if (status.Ok()) { - return StatusCodes::kOk; - } - if (status.value == connections::Status::kOutOfOrderApiCall) { - return StatusCodes::kOutOfOrderApiCall; - } - return StatusCodes::kError; -} - -} // namespace nearby::sharing::linux diff --git a/sharing/linux/nearby_sharing_service_linux.h b/sharing/linux/nearby_sharing_service_linux.h deleted file mode 100644 index 4315f7f7..00000000 --- a/sharing/linux/nearby_sharing_service_linux.h +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include - -#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 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 status_codes_callback) override; - - void UnregisterSendSurface( - TransferUpdateCallback* transfer_callback, - std::function status_codes_callback) override; - - void RegisterReceiveSurface( - TransferUpdateCallback* transfer_callback, ReceiveSurfaceState state, - Advertisement::BlockedVendorId vendor_id, - std::function status_codes_callback) override; - - void UnregisterReceiveSurface( - TransferUpdateCallback* transfer_callback, - std::function status_codes_callback) override; - - void ClearForegroundReceiveSurfaces( - std::function 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 - attachment_container, - std::function status_codes_callback) override; - - void Accept(int64_t share_target_id, - std::function - status_codes_callback) override; - - void Reject(int64_t share_target_id, - std::function - status_codes_callback) override; - - void Cancel(int64_t share_target_id, - std::function - status_codes_callback) override; - - void SetVisibility(proto::DeviceVisibility visibility, - absl::Duration expiration, - absl::AnyInvocable - 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 control_payload_ids; - std::unordered_set attachment_payload_ids; - std::unordered_set completed_attachment_payload_ids; - std::unordered_map text_attachment_id_by_payload_id; - std::unordered_map file_attachment_id_by_payload_id; - size_t expected_attachment_payload_count = 0; - bool transfer_complete_notified = false; - std::vector pending_outgoing_payloads; - }; - - struct ParsedAdvertisement { - ShareTargetType device_type = ShareTargetType::kUnknown; - std::optional device_name; - uint8_t vendor_id = 0; - }; - - void StartAdvertisingIfNeeded(); - void StopAdvertising(); - void StartDiscoveryIfNeeded(); - void StopDiscovery(); - - std::vector BuildAdvertisement( - const std::optional& device_name, - ShareTargetType device_type, uint8_t vendor_id) const; - - std::optional ParseAdvertisement( - absl::Span 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 GetEndpointIdForTarget( - int64_t share_target_id) const; - - std::optional 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 router_; - std::unique_ptr core_; - - std::unordered_set observers_; - std::unordered_map send_surfaces_; - std::unordered_map receive_surfaces_; - - std::unordered_map endpoint_to_target_; - std::unordered_map target_id_to_endpoint_; - std::unordered_map active_transfers_; - - std::optional 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_ diff --git a/sharing/linux/qml_tray_app/file_share_tray_controller.cc b/sharing/linux/qml_tray_app/file_share_tray_controller.cc index 3acdad43..bd706678 100644 --- a/sharing/linux/qml_tray_app/file_share_tray_controller.cc +++ b/sharing/linux/qml_tray_app/file_share_tray_controller.cc @@ -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(); diff --git a/sharing/linux/simple_example.cc b/sharing/linux/simple_example.cc deleted file mode 100644 index 04a46151..00000000 --- a/sharing/linux/simple_example.cc +++ /dev/null @@ -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 -#include -#include -#include -#include - -#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] << " [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(); - 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; -} diff --git a/sharing/nearby_sharing_service_factory.cc b/sharing/nearby_sharing_service_factory.cc index 63d1ea50..f2c4ea74 100644 --- a/sharing/nearby_sharing_service_factory.cc +++ b/sharing/nearby_sharing_service_factory.cc @@ -17,7 +17,6 @@ #include #include -#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_ = diff --git a/sharing/nearby_sharing_service_factory.h b/sharing/nearby_sharing_service_factory.h index 3fe117a9..c0862d5c 100644 --- a/sharing/nearby_sharing_service_factory.h +++ b/sharing/nearby_sharing_service_factory.h @@ -17,13 +17,18 @@ #include -#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 { diff --git a/sharing/nearby_sharing_service_impl.cc b/sharing/nearby_sharing_service_impl.cc index 7749dfda..9c3b5890 100644 --- a/sharing/nearby_sharing_service_impl.cc +++ b/sharing/nearby_sharing_service_impl.cc @@ -31,7 +31,6 @@ #include #include -#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" diff --git a/sharing/nearby_sharing_service_impl.h b/sharing/nearby_sharing_service_impl.h index 7b17c0e8..b737a8b3 100644 --- a/sharing/nearby_sharing_service_impl.h +++ b/sharing/nearby_sharing_service_impl.h @@ -27,8 +27,6 @@ #include #include -#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;