mirror of
https://github.com/kidfromjupiter/nearby.git
synced 2026-09-15 15:16:12 -04:00
166 lines
5.3 KiB
C++
166 lines
5.3 KiB
C++
#include <signal.h>
|
|
#include <unistd.h>
|
|
|
|
#include <atomic>
|
|
#include <condition_variable>
|
|
#include <cstdlib>
|
|
#include <iostream>
|
|
#include <mutex>
|
|
#include <optional>
|
|
#include <string>
|
|
|
|
#include <sdbus-c++/sdbus-c++.h>
|
|
|
|
#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<bool> g_interrupted = false;
|
|
sdbus::IConnection* g_bus = nullptr;
|
|
|
|
void HandleSignal(int signal) {
|
|
static_cast<void>(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 <typename Invoker>
|
|
NearbySharingService::StatusCodes WaitForStatus(Invoker invoker) {
|
|
std::mutex mutex;
|
|
std::condition_variable cv;
|
|
std::optional<NearbySharingService::StatusCodes> status;
|
|
invoker([&](NearbySharingService::StatusCodes callback_status) {
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex);
|
|
status = callback_status;
|
|
}
|
|
cv.notify_one();
|
|
});
|
|
|
|
std::unique_lock<std::mutex> 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<void>(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;
|
|
}
|