[refactor] share file transfer core across desktop and mobile

This commit is contained in:
kunkundi
2026-10-16 00:38:13 +08:00
parent 47e6385f9a
commit c4756b298b
13 changed files with 759 additions and 956 deletions
@@ -188,6 +188,7 @@ void GuiRuntime::HandlePresenceProbeTimeout() {
void GuiRuntime::HandleServerControllerDisconnected(
const std::string& remote_id, const char* reason) {
transfers_.Cancel(peer_events_.get(), remote_id);
preview_subscriptions_.Remove(remote_id);
keyboard_.ReleaseRemotePressedKeys(remote_id, reason);
#ifdef _WIN32
@@ -298,7 +299,10 @@ int GuiRuntime::ForceSignalReconnect() {
void GuiRuntime::CloseRemoteSession(std::shared_ptr<RemoteSession> props) {
if (!props || props->closing_.exchange(true)) return;
MuteRemoteAudio(props);
if (props->peer_events_) props->peer_events_->Deactivate();
if (props->peer_events_) {
props->peer_events_->Deactivate();
transfers_.Cancel(props->peer_events_.get());
}
props->connection_established_ = false;
props->streaming_ = false;
props->connection_status_.store(ConnectionStatus::Closed);
@@ -392,6 +396,7 @@ void GuiRuntime::CloseConnectionPeer() {
return;
}
peer_events_->Deactivate();
transfers_.Cancel(peer_events_.get());
announcements_.Reset();
std::vector<std::string> controllers;
{
@@ -439,6 +444,7 @@ void GuiRuntime::CloseAllRemoteSessions() {
}
void GuiRuntime::HandleSessionCleanup() {
transfers_.Poll();
auto completed = [](std::future<void>& task) {
if (!task.valid() || task.wait_for(std::chrono::seconds(0)) !=
std::future_status::ready) return false;
+4 -1
View File
@@ -26,7 +26,10 @@ GuiRuntime::GuiRuntime()
: clipboard_(*this), devices_(*this), transfers_(*this), settings_(*this),
keyboard_(*this) {}
GuiRuntime::~GuiRuntime() { WaitForSessionCleanup(); }
GuiRuntime::~GuiRuntime() {
transfers_.Shutdown();
WaitForSessionCleanup();
}
void GuiRuntime::SendRemoteInput(const RemoteAction& action) {
const bool mouse = action.type == ControlType::mouse;
@@ -101,38 +101,7 @@ void PeerEventHandler::OnReceiveDataBuffer(
source_id == runtime->clipboard_label_))
return;
if (source_id == runtime->file_label_) {
std::string remote_user_id = std::string(user_id, user_id_size);
static FileReceiver receiver;
// Update output directory from config
std::string configured_path =
runtime->config_center_->GetFileTransferSavePath();
if (!configured_path.empty()) {
receiver.SetOutputDir(PathFromUtf8(configured_path));
} else if (receiver.OutputDir().empty()) {
receiver = FileReceiver(); // re-init with default desktop path
}
receiver.SetOnSendAck([runtime,
remote_user_id](const FileTransferAck &ack) -> int {
const auto encoded_ack = EncodeFileTransferAck(ack);
bool is_server_sending = remote_user_id.rfind("C-", 0) != 0;
if (is_server_sending) {
auto props =
runtime->FindRemoteSession(remote_user_id);
if (props) {
PeerPtr *peer = props->peer_;
return SendReliableDataFrame(
peer, encoded_ack.data(), encoded_ack.size(),
runtime->file_feedback_label_.c_str());
}
}
return SendReliableDataFrame(
runtime->peer_, encoded_ack.data(), encoded_ack.size(),
runtime->file_feedback_label_.c_str());
});
receiver.OnData(data, size);
runtime->transfers_.Receive(data, size, handler, std::string(user_id, user_id_size));
return;
} else if (source_id == runtime->clipboard_label_) {
if (size > 0) {
@@ -148,7 +117,7 @@ void PeerEventHandler::OnReceiveDataBuffer(
}
return;
} else if (source_id == runtime->file_feedback_label_) {
runtime->transfers_.HandleAck(data, size);
runtime->transfers_.HandleAck(data, size, handler, std::string(user_id, user_id_size));
return;
}
@@ -61,7 +61,9 @@ void PeerEventHandler::SendClientInfo(PeerPtr* peer,
}
}
PeerEventHandler::PeerEventHandler(GuiRuntime& owner) : owner_(owner) {}
PeerEventHandler::PeerEventHandler(GuiRuntime& owner) : owner_(owner) {
owner_.transfers_.Connected(this, "");
}
void PeerEventHandler::OnSignalMessage(const char* message, size_t size,
void* user_data) {
@@ -257,6 +259,9 @@ void PeerEventHandler::OnConnectionStatus(ConnectionStatus status,
if (!runtime) return;
std::string remote_id(user_id, user_id_size);
if (status == ConnectionStatus::Connected) runtime->transfers_.Connected(handler, remote_id);
else if (status == ConnectionStatus::Disconnected || status == ConnectionStatus::Failed ||
status == ConnectionStatus::Closed) runtime->transfers_.Cancel(handler, remote_id);
std::shared_ptr<GuiRuntime::RemoteSession> props;
{
std::shared_lock lock(runtime->remote_sessions_mutex_);
@@ -44,7 +44,7 @@ struct FileTransferState {
std::chrono::steady_clock::time_point file_send_start_time_;
std::chrono::steady_clock::time_point file_send_last_update_time_;
uint64_t file_send_last_bytes_ = 0;
bool file_transfer_window_visible_ = false;
std::atomic<bool> file_transfer_window_visible_ = false;
std::atomic<uint32_t> current_file_id_{0};
struct QueuedFile {