Merge remote-tracking branch 'github/master' into sigma

# Conflicts:
#	flutter/lib/desktop/widgets/remote_menubar.dart
This commit is contained in:
sjpark
2023-02-25 11:37:12 +09:00
238 changed files with 8183 additions and 4234 deletions

View File

@@ -1,29 +1,33 @@
#[cfg(not(any(target_os = "android", target_os = "ios")))]
use std::collections::HashMap;
use std::ops::{Deref, DerefMut};
use std::str::FromStr;
use std::sync::{Arc, Mutex, RwLock};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
use std::sync::{
atomic::{AtomicBool, AtomicUsize, Ordering},
Arc, Mutex, RwLock,
};
use std::time::{Duration, SystemTime};
use async_trait::async_trait;
use bytes::Bytes;
use rdev::{Event, EventType::*};
use uuid::Uuid;
use hbb_common::{allow_err, message_proto::*};
use hbb_common::{fs, get_version_number, log, Stream};
use hbb_common::config::{Config, LocalConfig, PeerConfig, RS_PUB_KEY};
use hbb_common::rendezvous_proto::ConnType;
use hbb_common::tokio::{self, sync::mpsc};
use hbb_common::{allow_err, message_proto::*};
use hbb_common::{fs, get_version_number, log, Stream};
use crate::{client::Data, client::Interface};
use crate::client::{
check_if_retry, FileManager, handle_hash, handle_login_error, handle_login_from_ui,
handle_test_delay, input_os_password, Key, KEY_MAP, load_config, LoginConfigHandler,
QualityStatus, send_mouse, start_video_audio_threads,
};
use crate::client::io_loop::Remote;
use crate::client::{
check_if_retry, handle_hash, handle_login_error, handle_login_from_ui, handle_test_delay,
input_os_password, load_config, send_mouse, start_video_audio_threads, FileManager, Key,
LoginConfigHandler, QualityStatus, KEY_MAP,
};
use crate::common::{self, GrabState};
use crate::keyboard;
use crate::{client::Data, client::Interface};
pub static IS_IN: AtomicBool = AtomicBool::new(false);
@@ -36,9 +40,37 @@ pub struct Session<T: InvokeUiSession> {
pub sender: Arc<RwLock<Option<mpsc::UnboundedSender<Data>>>>,
pub thread: Arc<Mutex<Option<std::thread::JoinHandle<()>>>>,
pub ui_handler: T,
pub server_keyboard_enabled: Arc<RwLock<bool>>,
pub server_file_transfer_enabled: Arc<RwLock<bool>>,
pub server_clipboard_enabled: Arc<RwLock<bool>>,
}
#[derive(Clone)]
pub struct SessionPermissionConfig {
pub lc: Arc<RwLock<LoginConfigHandler>>,
pub server_keyboard_enabled: Arc<RwLock<bool>>,
pub server_file_transfer_enabled: Arc<RwLock<bool>>,
pub server_clipboard_enabled: Arc<RwLock<bool>>,
}
impl SessionPermissionConfig {
pub fn is_text_clipboard_required(&self) -> bool {
*self.server_clipboard_enabled.read().unwrap()
&& *self.server_keyboard_enabled.read().unwrap()
&& !self.lc.read().unwrap().disable_clipboard.v
}
}
impl<T: InvokeUiSession> Session<T> {
pub fn get_permission_config(&self) -> SessionPermissionConfig {
SessionPermissionConfig {
lc: self.lc.clone(),
server_keyboard_enabled: self.server_keyboard_enabled.clone(),
server_file_transfer_enabled: self.server_file_transfer_enabled.clone(),
server_clipboard_enabled: self.server_clipboard_enabled.clone(),
}
}
pub fn is_file_transfer(&self) -> bool {
self.lc
.read()
@@ -127,6 +159,12 @@ impl<T: InvokeUiSession> Session<T> {
self.lc.read().unwrap().is_privacy_mode_supported()
}
pub fn is_text_clipboard_required(&self) -> bool {
*self.server_clipboard_enabled.read().unwrap()
&& *self.server_keyboard_enabled.read().unwrap()
&& !self.lc.read().unwrap().disable_clipboard.v
}
pub fn refresh_video(&self) {
self.send(Data::Message(LoginConfigHandler::refresh()));
}
@@ -521,7 +559,7 @@ impl<T: InvokeUiSession> Session<T> {
KeyRelease(key)
};
let event = Event {
time: std::time::SystemTime::now(),
time: SystemTime::now(),
unicode: None,
code: keycode as _,
scan_code: scancode as _,
@@ -608,9 +646,13 @@ impl<T: InvokeUiSession> Session<T> {
}
}
pub fn reconnect(&self) {
pub fn reconnect(&self, force_relay: bool) {
self.send(Data::Close);
let cloned = self.clone();
// override only if true
if true == force_relay {
cloned.lc.write().unwrap().force_relay = true;
}
let mut lock = self.thread.lock().unwrap();
lock.take().map(|t| t.join());
*lock = Some(std::thread::spawn(move || {
@@ -748,13 +790,57 @@ impl<T: InvokeUiSession> Session<T> {
}
}
pub fn change_resolution(&self, width: i32, height: i32) {
let mut misc = Misc::new();
misc.set_change_resolution(Resolution {
width,
height,
..Default::default()
});
let mut msg = Message::new();
msg.set_misc(misc);
self.send(Data::Message(msg));
}
pub fn request_voice_call(&self) {
self.send(Data::NewVoiceCall);
}
pub fn close_voice_call(&self) {
self.send(Data::CloseVoiceCall);
}
pub fn show_relay_hint(
&mut self,
last_recv_time: tokio::time::Instant,
msgtype: &str,
title: &str,
text: &str,
) -> bool {
let duration = Duration::from_secs(3);
let counter_interval = 3;
let lock = self.lc.read().unwrap();
let success_time = lock.success_time;
let direct = lock.direct.unwrap_or(false);
let received = lock.received;
drop(lock);
if let Some(success_time) = success_time {
if direct && last_recv_time.duration_since(success_time) < duration {
let retry_for_relay = direct && !received;
let retry = check_if_retry(msgtype, title, text, retry_for_relay);
if retry && !retry_for_relay {
self.lc.write().unwrap().direct_error_counter += 1;
if self.lc.read().unwrap().direct_error_counter % counter_interval == 0 {
#[cfg(feature = "flutter")]
return true;
}
}
} else {
self.lc.write().unwrap().direct_error_counter = 0;
}
}
false
}
}
pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
@@ -764,6 +850,7 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
fn set_display(&self, x: i32, y: i32, w: i32, h: i32, cursor_embedded: bool);
fn switch_display(&self, display: &SwitchDisplay);
fn set_peer_info(&self, peer_info: &PeerInfo); // flutter
fn set_displays(&self, displays: &Vec<DisplayInfo>);
fn on_connected(&self, conn_type: ConnType);
fn update_privacy_mode(&self);
fn set_permission(&self, name: &str, value: bool);
@@ -789,7 +876,7 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
fn update_block_input_state(&self, on: bool);
fn job_progress(&self, id: i32, file_num: i32, speed: f64, finished_size: f64);
fn adapt_size(&self);
fn on_rgba(&self, data: &[u8]);
fn on_rgba(&self, data: &mut Vec<u8>);
fn msgbox(&self, msgtype: &str, title: &str, text: &str, link: &str, retry: bool);
#[cfg(any(target_os = "android", target_os = "ios"))]
fn clipboard(&self, content: String);
@@ -799,6 +886,8 @@ pub trait InvokeUiSession: Send + Sync + Clone + 'static + Sized + Default {
fn on_voice_call_closed(&self, reason: &str);
fn on_voice_call_waiting(&self);
fn on_voice_call_incoming(&self);
fn get_rgba(&self) -> *const u8;
fn next_rgba(&self);
}
impl<T: InvokeUiSession> Deref for Session<T> {
@@ -888,6 +977,7 @@ impl<T: InvokeUiSession> Interface for Session<T> {
"Connected, waiting for image...",
"",
);
self.lc.write().unwrap().success_time = Some(tokio::time::Instant::now());
}
self.on_connected(self.lc.read().unwrap().conn_type);
#[cfg(windows)]
@@ -1049,7 +1139,7 @@ pub async fn io_loop<T: InvokeUiSession>(handler: Session<T>) {
let frame_count = Arc::new(AtomicUsize::new(0));
let frame_count_cl = frame_count.clone();
let ui_handler = handler.ui_handler.clone();
let (video_sender, audio_sender) = start_video_audio_threads(move |data: &[u8]| {
let (video_sender, audio_sender) = start_video_audio_threads(move |data: &mut Vec<u8>| {
frame_count_cl.fetch_add(1, Ordering::Relaxed);
ui_handler.on_rgba(data);
});