Merge pull request #5623 from 21pages/cm_file

add file log page to cm
This commit is contained in:
RustDesk
2023-09-07 20:33:00 +08:00
committed by GitHub
14 changed files with 519 additions and 39 deletions

View File

@@ -483,9 +483,13 @@ impl<T: InvokeUiSession> Remote<T> {
// peer is not windows, need transform \ to /
fs::transform_windows_path(&mut files);
}
let total_size = job.total_size();
self.read_jobs.push(job);
self.timer = time::interval(MILLI1);
allow_err!(peer.send(&fs::new_receive(id, to, file_num, files)).await);
allow_err!(
peer.send(&fs::new_receive(id, to, file_num, files, total_size))
.await
);
}
}
}
@@ -568,7 +572,8 @@ impl<T: InvokeUiSession> Remote<T> {
id,
job.path.to_string_lossy().to_string(),
job.file_num,
job.files.clone()
job.files.clone(),
job.total_size(),
))
.await
);

View File

@@ -907,6 +907,10 @@ pub mod connection_manager {
let client_json = serde_json::to_string(&client).unwrap_or("".into());
self.push_event("update_voice_call_state", vec![("client", &client_json)]);
}
fn file_transfer_log(&self, log: String) {
self.push_event("cm_file_transfer_log", vec![("log", &log.to_string())]);
}
}
impl FlutterHandler {

View File

@@ -70,6 +70,8 @@ pub enum FS {
file_num: i32,
files: Vec<(String, u64)>,
overwrite_detection: bool,
total_size: u64,
conn_id: i32,
},
CancelWrite {
id: i32,
@@ -231,6 +233,7 @@ pub enum Data {
Plugin(Plugin),
#[cfg(windows)]
SyncWinCpuUsage(Option<f64>),
FileTransferLog(String),
}
#[tokio::main(flavor = "current_thread")]

View File

@@ -188,6 +188,7 @@ pub struct Connection {
lr: LoginRequest,
last_recv_time: Arc<Mutex<Instant>>,
chat_unanswered: bool,
file_transferred: bool,
#[cfg(windows)]
portable: PortableState,
from_switch: bool,
@@ -320,6 +321,7 @@ impl Connection {
lr: Default::default(),
last_recv_time: Arc::new(Mutex::new(Instant::now())),
chat_unanswered: false,
file_transferred: false,
#[cfg(windows)]
portable: Default::default(),
from_switch: false,
@@ -399,6 +401,7 @@ impl Connection {
}
ipc::Data::Close => {
conn.chat_unanswered = false; // seen
conn.file_transferred = false; //seen
conn.send_close_reason_no_retry("").await;
conn.on_close("connection manager", true).await;
break;
@@ -536,9 +539,17 @@ impl Connection {
},
_ = conn.file_timer.tick() => {
if !conn.read_jobs.is_empty() {
if let Err(err) = fs::handle_read_jobs(&mut conn.read_jobs, &mut conn.stream).await {
conn.on_close(&err.to_string(), false).await;
break;
conn.send_to_cm(ipc::Data::FileTransferLog(fs::serialize_transfer_jobs(&conn.read_jobs)));
match fs::handle_read_jobs(&mut conn.read_jobs, &mut conn.stream).await {
Ok(log) => {
if !log.is_empty() {
conn.send_to_cm(ipc::Data::FileTransferLog(log));
}
}
Err(err) => {
conn.on_close(&err.to_string(), false).await;
break;
}
}
} else {
conn.file_timer = time::interval_at(Instant::now() + SEC30, SEC30);
@@ -1717,6 +1728,7 @@ impl Connection {
}
}
Some(file_action::Union::Send(s)) => {
// server to client
let id = s.id;
let od = can_enable_overwrite_detection(get_version_number(
&self.lr.version,
@@ -1734,10 +1746,12 @@ impl Connection {
Err(err) => {
self.send(fs::new_error(id, err, 0)).await;
}
Ok(job) => {
Ok(mut job) => {
self.send(fs::new_dir(id, path, job.files().to_vec()))
.await;
let mut files = job.files().to_owned();
job.is_remote = true;
job.conn_id = self.inner.id();
self.read_jobs.push(job);
self.file_timer = time::interval(MILLI1);
self.post_file_audit(
@@ -1751,8 +1765,10 @@ impl Connection {
);
}
}
self.file_transferred = true;
}
Some(file_action::Union::Receive(r)) => {
// client to server
// note: 1.1.10 introduced identical file detection, which breaks original logic of send/recv files
// whenever got send/recv request, check peer version to ensure old version of rustdesk
let od = can_enable_overwrite_detection(get_version_number(
@@ -1769,6 +1785,8 @@ impl Connection {
.map(|f| (f.name, f.modified_time))
.collect(),
overwrite_detection: od,
total_size: r.total_size,
conn_id: self.inner.id(),
});
self.post_file_audit(
FileAuditType::RemoteReceive,
@@ -1780,6 +1798,7 @@ impl Connection {
.collect(),
json!({}),
);
self.file_transferred = true;
}
Some(file_action::Union::RemoveDir(d)) => {
self.send_fs(ipc::FS::RemoveDir {
@@ -1803,6 +1822,11 @@ impl Connection {
}
Some(file_action::Union::Cancel(c)) => {
self.send_fs(ipc::FS::CancelWrite { id: c.id });
if let Some(job) = fs::get_job_immutable(c.id, &self.read_jobs) {
self.send_to_cm(ipc::Data::FileTransferLog(
fs::serialize_transfer_job(job, false, true, ""),
));
}
fs::remove_job(c.id, &mut self.read_jobs);
}
Some(file_action::Union::SendConfirm(r)) => {
@@ -2254,7 +2278,7 @@ impl Connection {
lock_screen().await;
}
#[cfg(not(any(target_os = "android", target_os = "ios")))]
let data = if self.chat_unanswered {
let data = if self.chat_unanswered || self.file_transferred {
ipc::Data::Disconnected
} else {
ipc::Data::Close

View File

@@ -59,13 +59,11 @@ impl InvokeUiCM for SciterHandler {
fn update_voice_call_state(&self, client: &crate::ui_cm_interface::Client) {
self.call(
"updateVoiceCallState",
&make_args!(
client.id,
client.in_voice_call,
client.incoming_voice_call
),
&make_args!(client.id, client.in_voice_call, client.incoming_voice_call),
);
}
fn file_transfer_log(&self, _log: String) {}
}
impl SciterHandler {

View File

@@ -99,6 +99,8 @@ pub trait InvokeUiCM: Send + Clone + 'static + Sized {
fn show_elevation(&self, show: bool);
fn update_voice_call_state(&self, client: &Client);
fn file_transfer_log(&self, log: String);
}
impl<T: InvokeUiCM> Deref for ConnectionManager<T> {
@@ -357,6 +359,7 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
);
}
}
let (tx_log, mut rx_log) = mpsc::unbounded_channel::<String>();
self.running = false;
loop {
@@ -403,11 +406,16 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
if let ipc::FS::WriteBlock { id, file_num, data: _, compressed } = fs {
if let Ok(bytes) = self.stream.next_raw().await {
fs = ipc::FS::WriteBlock{id, file_num, data:bytes.into(), compressed};
handle_fs(fs, &mut write_jobs, &self.tx).await;
handle_fs(fs, &mut write_jobs, &self.tx, Some(&tx_log)).await;
}
} else {
handle_fs(fs, &mut write_jobs, &self.tx).await;
handle_fs(fs, &mut write_jobs, &self.tx, Some(&tx_log)).await;
}
let log = fs::serialize_transfer_jobs(&write_jobs);
self.cm.ui_handler.file_transfer_log(log);
}
Data::FileTransferLog(log) => {
self.cm.ui_handler.file_transfer_log(log);
}
#[cfg(not(any(target_os = "android", target_os = "ios")))]
Data::ClipboardFile(_clip) => {
@@ -509,6 +517,9 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
//
}
},
Some(job_log) = rx_log.recv() => {
self.cm.ui_handler.file_transfer_log(job_log);
}
}
}
}
@@ -632,7 +643,7 @@ pub async fn start_listen<T: InvokeUiCM>(
cm.new_message(current_id, text);
}
Some(Data::FS(fs)) => {
handle_fs(fs, &mut write_jobs, &tx).await;
handle_fs(fs, &mut write_jobs, &tx, None).await;
}
Some(Data::Close) => {
break;
@@ -647,7 +658,14 @@ pub async fn start_listen<T: InvokeUiCM>(
}
#[cfg(not(any(target_os = "ios")))]
async fn handle_fs(fs: ipc::FS, write_jobs: &mut Vec<fs::TransferJob>, tx: &UnboundedSender<Data>) {
async fn handle_fs(
fs: ipc::FS,
write_jobs: &mut Vec<fs::TransferJob>,
tx: &UnboundedSender<Data>,
tx_log: Option<&UnboundedSender<String>>,
) {
use hbb_common::fs::serialize_transfer_job;
match fs {
ipc::FS::ReadDir {
dir,
@@ -674,10 +692,12 @@ async fn handle_fs(fs: ipc::FS, write_jobs: &mut Vec<fs::TransferJob>, tx: &Unbo
file_num,
mut files,
overwrite_detection,
total_size,
conn_id,
} => {
// cm has no show_hidden context
// dummy remote, show_hidden, is_remote
write_jobs.push(fs::TransferJob::new_write(
let mut job = fs::TransferJob::new_write(
id,
"".to_string(),
path,
@@ -693,11 +713,17 @@ async fn handle_fs(fs: ipc::FS, write_jobs: &mut Vec<fs::TransferJob>, tx: &Unbo
})
.collect(),
overwrite_detection,
));
);
job.total_size = total_size;
job.conn_id = conn_id;
write_jobs.push(job);
}
ipc::FS::CancelWrite { id } => {
if let Some(job) = fs::get_job(id, write_jobs) {
job.remove_download_file();
tx_log.map(|tx: &UnboundedSender<String>| {
tx.send(serialize_transfer_job(job, false, true, ""))
});
fs::remove_job(id, write_jobs);
}
}
@@ -705,11 +731,13 @@ async fn handle_fs(fs: ipc::FS, write_jobs: &mut Vec<fs::TransferJob>, tx: &Unbo
if let Some(job) = fs::get_job(id, write_jobs) {
job.modify_time();
send_raw(fs::new_done(id, file_num), tx);
tx_log.map(|tx| tx.send(serialize_transfer_job(job, true, false, "")));
fs::remove_job(id, write_jobs);
}
}
ipc::FS::WriteError { id, file_num, err } => {
if let Some(job) = fs::get_job(id, write_jobs) {
tx_log.map(|tx| tx.send(serialize_transfer_job(job, false, false, &err)));
send_raw(fs::new_error(job.id(), err, file_num), tx);
fs::remove_job(job.id(), write_jobs);
}