Merge remote-tracking branch 'origin/master' into feat/x11/clipboard-file/init

Signed-off-by: 蔡略 <cailue@bupt.edu.cn>
This commit is contained in:
蔡略
2023-09-08 20:09:57 +08:00
302 changed files with 14257 additions and 6606 deletions

View File

@@ -69,7 +69,6 @@ struct IpcTaskRunner<T: InvokeUiCM> {
rx: mpsc::UnboundedReceiver<Data>,
close: bool,
running: bool,
authorized: bool,
conn_id: i32,
#[cfg(any(target_os = "windows", target_os = "linux"))]
file_transfer_enabled: bool,
@@ -101,6 +100,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> {
@@ -163,6 +164,16 @@ impl<T: InvokeUiCM> ConnectionManager<T> {
self.ui_handler.add_connection(&client);
}
#[inline]
fn is_authorized(&self, id: i32) -> bool {
CLIENTS
.read()
.unwrap()
.get(&id)
.map(|c| c.authorized)
.unwrap_or(false)
}
fn remove_connection(&self, id: i32, close: bool) {
if close {
CLIENTS.write().unwrap().remove(&id);
@@ -318,12 +329,15 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
// for tmp use, without real conn id
let mut write_jobs: Vec<fs::TransferJob> = Vec::new();
#[cfg(any(target_os = "windows", target_os = "linux"))]
let is_authorized = self.cm.is_authorized(self.conn_id);
#[cfg(any(target_os = "windows", target_os = "linux"))]
let rx_clip1;
let mut rx_clip;
let _tx_clip;
#[cfg(any(target_os = "windows", target_os = "linux"))]
if self.conn_id > 0 && self.authorized {
if self.conn_id > 0 && is_authorized {
rx_clip1 = clipboard::get_rx_cliprdr_server(self.conn_id);
rx_clip = rx_clip1.lock().await;
} else {
@@ -347,6 +361,7 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
);
}
}
let (tx_log, mut rx_log) = mpsc::unbounded_channel::<String>();
self.running = false;
loop {
@@ -362,7 +377,6 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
Data::Login{id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, file_transfer_enabled: _file_transfer_enabled, restart, recording, from_switch} => {
log::debug!("conn_id: {}", id);
self.cm.add_connection(id, is_file_transfer, port_forward, peer_id, name, authorized, keyboard, clipboard, audio, file, restart, recording, from_switch,self.tx.clone());
self.authorized = authorized;
self.conn_id = id;
#[cfg(windows)]
{
@@ -394,11 +408,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) => {
@@ -414,6 +433,10 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
if stop {
ContextSend::set_is_stopped();
} else {
if !is_authorized {
log::debug!("Clipboard message from client peer, but not authorized");
continue;
}
let conn_id = self.conn_id;
let _ = ContextSend::proc(|context| -> ResultType<()> {
context.server_clip_file(conn_id, _clip)
@@ -456,16 +479,24 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
}
}
Some(data) = self.rx.recv() => {
if let Data::SwitchPermission{name: _name, enabled: _enabled} = &data {
#[cfg(windows)]
if _name == "file" {
self.file_transfer_enabled = *_enabled;
}
}
if self.stream.send(&data).await.is_err() {
break;
}
}
match &data {
Data::SwitchPermission{name: _name, enabled: _enabled} => {
#[cfg(windows)]
if _name == "file" {
self.file_transfer_enabled = *_enabled;
}
}
Data::Authorize => {
self.running = true;
break;
}
_ => {
}
}
},
clip_file = rx_clip.recv() => match clip_file {
Some(_clip) => {
#[cfg(any(target_os = "windows", target_os ="linux"))]
@@ -489,6 +520,9 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
//
}
},
Some(job_log) = rx_log.recv() => {
self.cm.ui_handler.file_transfer_log(job_log);
}
}
}
}
@@ -503,7 +537,6 @@ impl<T: InvokeUiCM> IpcTaskRunner<T> {
rx,
close: true,
running: true,
authorized: false,
conn_id: 0,
#[cfg(any(target_os = "windows", target_os = "linux"))]
file_transfer_enabled: false,
@@ -535,7 +568,6 @@ pub async fn start_ipc<T: InvokeUiCM>(cm: ConnectionManager<T>) {
e
);
}
allow_err!(crate::privacy_win_mag::start());
});
#[cfg(target_os = "windows")]
@@ -614,7 +646,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;
@@ -629,7 +661,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,
@@ -656,10 +695,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,
@@ -675,11 +716,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);
}
}
@@ -687,11 +734,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);
}