#include #include #include #include #include #include #include #include #include #include #include "absl/time/time.h" #include "connections/implementation/flags/nearby_connections_feature_flags.h" #include "internal/flags/nearby_flags.h" #include "sharing/flags/generated/nearby_sharing_feature_flags.h" #include "sharing/linux/daemon/nearby_sharing_dbus_service.h" #include "sharing/linux/nearby_noop_analytics_recorder.h" #include "sharing/linux/platform/linux_sharing_platform.h" #include "sharing/nearby_sharing_service.h" #include "sharing/nearby_sharing_service_factory.h" #include "sharing/nearby_sharing_settings.h" #include "sharing/proto/enums.pb.h" namespace nearby::sharing::linux { namespace { std::atomic g_interrupted = false; sdbus::IConnection* g_bus = nullptr; void HandleSignal(int signal) { static_cast(signal); g_interrupted = true; if (g_bus != nullptr) { g_bus->leaveEventLoop(); } } std::string GetHostname() { char hostname[256] = {}; if (gethostname(hostname, sizeof(hostname)) == 0 && hostname[0] != '\0') { return std::string(hostname); } return "LinuxShare"; } std::string GetDeviceName(int argc, char** argv) { for (int i = 1; i < argc; ++i) { std::string arg = argv[i]; if (arg == "--name" && i + 1 < argc) { return argv[i + 1]; } } const char* env_name = std::getenv("NEARBY_DEVICE_NAME"); if (env_name != nullptr && *env_name != '\0') { return env_name; } return GetHostname(); } template NearbySharingService::StatusCodes WaitForStatus(Invoker invoker) { std::mutex mutex; std::condition_variable cv; std::optional status; invoker([&](NearbySharingService::StatusCodes callback_status) { { std::lock_guard lock(mutex); status = callback_status; } cv.notify_one(); }); std::unique_lock lock(mutex); cv.wait(lock, [&] { return status.has_value(); }); return *status; } void ConfigureFlags() { nearby::NearbyFlags::GetInstance().OverrideBoolFlagValue( nearby::sharing::config_package_nearby::nearby_sharing_feature:: kEnableBleForTransfer, true); 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); } bool ConfigureSharingService(NearbySharingService& service, const std::string& device_name) { service.GetSettings()->SetDataUsage(proto::WIFI_ONLY_DATA_USAGE); service.GetSettings()->SetDeviceName( device_name, [](DeviceNameValidationResult validation_result) { static_cast(validation_result); }); auto status = WaitForStatus([&](auto callback) { service.SetVisibility(proto::DEVICE_VISIBILITY_EVERYONE, absl::ZeroDuration(), std::move(callback)); }); if (status != NearbySharingService::StatusCodes::kOk) { std::cerr << "SetVisibility failed: " << NearbySharingService::StatusCodeToString(status) << std::endl; return false; } return true; } } // namespace } // namespace nearby::sharing::linux int main(int argc, char** argv) { signal(SIGINT, nearby::sharing::linux::HandleSignal); signal(SIGTERM, nearby::sharing::linux::HandleSignal); nearby::sharing::linux::ConfigureFlags(); const std::string device_name = nearby::sharing::linux::GetDeviceName(argc, argv); auto analytics_recorder = nearby::sharing::linux::NoOpAnalyticsRecorder(); auto linux_platform = nearby::sharing::linux::LinuxSharingPlatform(device_name); auto* service = nearby::sharing::NearbySharingServiceFactory::GetInstance() ->CreateSharingService(linux_platform, &analytics_recorder, /*event_logger=*/nullptr, /*supports_file_sync=*/false); if (service == nullptr) { std::cerr << "failed to create NearbySharingService" << std::endl; return 1; } if (!nearby::sharing::linux::ConfigureSharingService(*service, device_name)) { nearby::sharing::linux::WaitForStatus( [&](auto callback) { service->Shutdown(std::move(callback)); }); return 1; } auto bus = sdbus::createSessionBusConnection( sdbus::ServiceName("com.google.nearby.sharing")); nearby::sharing::linux::g_bus = bus.get(); auto object = sdbus::createObject( *bus, sdbus::ObjectPath("/com/google/nearby/sharing")); nearby::sharing::linux::NearbySharingDbusService dbus_service( *object, *service, [&bus]() { bus->leaveEventLoop(); }); dbus_service.EmitStatusChanged(); try { bus->enterEventLoop(); } catch (const sdbus::Error& error) { std::cerr << "D-Bus event loop failed: " << error.getName() << ": " << error.getMessage() << std::endl; dbus_service.ShutdownService(); nearby::sharing::linux::g_bus = nullptr; return 1; } dbus_service.ShutdownService(); nearby::sharing::linux::g_bus = nullptr; return nearby::sharing::linux::g_interrupted ? 130 : 0; }