Merge pull request #5256 from dignow/refact/separate_remote_window

Refact/separate remote window
This commit is contained in:
RustDesk
2023-08-06 09:31:05 +08:00
committed by GitHub
58 changed files with 727 additions and 320 deletions

View File

@@ -1008,6 +1008,11 @@ impl<T: InvokeUiSession> Remote<T> {
}
}
Some(login_response::Union::PeerInfo(pi)) => {
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
self.handler.cache_flutter.write().unwrap().pi = pi.clone();
}
self.handler.handle_peer_info(pi);
#[cfg(not(feature = "flutter"))]
self.check_clipboard_file_context();
@@ -1055,9 +1060,22 @@ impl<T: InvokeUiSession> Remote<T> {
_ => {}
},
Some(message::Union::CursorData(cd)) => {
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
let mut lock = self.handler.cache_flutter.write().unwrap();
if !lock.cursor_data.contains_key(&cd.id) {
lock.cursor_data.insert(cd.id, cd.clone());
}
}
self.handler.set_cursor_data(cd);
}
Some(message::Union::CursorId(id)) => {
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
self.handler.cache_flutter.write().unwrap().cursor_id = id;
}
self.handler.set_cursor_id(id.to_string());
}
Some(message::Union::CursorPosition(cp)) => {
@@ -1274,6 +1292,16 @@ impl<T: InvokeUiSession> Remote<T> {
}
}
Some(misc::Union::SwitchDisplay(s)) => {
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
{
self.handler
.cache_flutter
.write()
.unwrap()
.sp
.replace(s.clone());
}
self.handler.handle_peer_switch_display(&s);
self.video_sender.send(MediaData::Reset).ok();
if s.width > 0 && s.height > 0 {

View File

@@ -186,7 +186,7 @@ pub type FlutterRgbaRendererPluginOnRgba = unsafe extern "C" fn(
#[derive(Clone)]
struct VideoRenderer {
// TextureRgba pointer in flutter native.
ptr: usize,
ptr: Arc<RwLock<usize>>,
width: usize,
height: usize,
on_rgba_func: Option<Symbol<'static, FlutterRgbaRendererPluginOnRgba>>,
@@ -214,7 +214,7 @@ impl Default for VideoRenderer {
}
};
Self {
ptr: 0,
ptr: Default::default(),
width: 0,
height: 0,
on_rgba_func,
@@ -231,7 +231,8 @@ impl VideoRenderer {
}
pub fn on_rgba(&self, rgba: &mut scrap::ImageRgb) {
if self.ptr == usize::default() {
let ptr = self.ptr.read().unwrap();
if *ptr == usize::default() {
return;
}
@@ -243,7 +244,7 @@ impl VideoRenderer {
if let Some(func) = &self.on_rgba_func {
unsafe {
func(
self.ptr as _,
*ptr as _,
rgba.raw.as_ptr() as _,
rgba.raw.len() as _,
rgba.w as _,
@@ -328,7 +329,7 @@ impl FlutterHandler {
#[inline]
#[cfg(feature = "flutter_texture_render")]
pub fn register_texture(&mut self, ptr: usize) {
self.renderer.write().unwrap().ptr = ptr;
*self.renderer.read().unwrap().ptr.write().unwrap() = ptr;
}
#[inline]
@@ -789,11 +790,15 @@ pub fn session_start_(
);
#[cfg(not(feature = "flutter_texture_render"))]
log::info!("Session {} start, render by flutter paint widget", id);
let is_pre_added = session.event_stream.read().unwrap().is_some();
session.close_event_stream();
*session.event_stream.write().unwrap() = Some(event_stream);
let session = session.clone();
std::thread::spawn(move || {
io_loop(session);
});
if !is_pre_added {
let session = session.clone();
std::thread::spawn(move || {
io_loop(session);
});
}
Ok(())
} else {
bail!("No session with peer id {}", id)

View File

@@ -15,7 +15,7 @@ use flutter_rust_bridge::{StreamSink, SyncReturn};
use hbb_common::allow_err;
use hbb_common::{
config::{self, LocalConfig, PeerConfig, PeerInfoSerde},
fs, log,
fs, lazy_static, log,
message_proto::KeyboardMode,
ResultType,
};
@@ -24,11 +24,19 @@ use std::{
ffi::{CStr, CString},
os::raw::c_char,
str::FromStr,
sync::{
atomic::{AtomicI32, Ordering},
Arc,
},
time::SystemTime,
};
pub type SessionID = uuid::Uuid;
lazy_static::lazy_static! {
static ref TEXTURE_RENDER_KEY: Arc<AtomicI32> = Arc::new(AtomicI32::new(0));
}
fn initialize(app_dir: &str) {
*config::APP_DIR.write().unwrap() = app_dir.to_owned();
#[cfg(target_os = "android")]
@@ -197,6 +205,30 @@ pub fn session_set_flutter_config(session_id: SessionID, k: String, v: String) {
}
}
pub fn session_get_flutter_config_by_peer_id(id: String, k: String) -> Option<String> {
if let Some((_, session)) = SESSIONS.read().unwrap().iter().find(|(_, s)| s.id == id) {
Some(session.get_flutter_config(k))
} else {
None
}
}
pub fn session_set_flutter_config_by_peer_id(id: String, k: String, v: String) {
if let Some((_, session)) = SESSIONS
.write()
.unwrap()
.iter_mut()
.find(|(_, s)| s.id == id)
{
session.save_flutter_config(k, v);
}
}
pub fn get_next_texture_key() -> SyncReturn<i32> {
let k = TEXTURE_RENDER_KEY.fetch_add(1, Ordering::SeqCst) + 1;
SyncReturn(k)
}
pub fn get_local_flutter_config(k: String) -> SyncReturn<String> {
SyncReturn(ui_interface::get_local_flutter_config(k))
}
@@ -569,6 +601,14 @@ pub fn session_change_resolution(session_id: SessionID, display: i32, width: i32
}
}
pub fn session_ready_to_new_window(session_id: SessionID) {
#[cfg(not(any(target_os = "android", target_os = "ios")))]
if let Some(session) = SESSIONS.write().unwrap().get_mut(&session_id) {
session.restore_flutter_cache();
session.refresh_video();
}
}
pub fn session_set_size(_session_id: SessionID, _width: usize, _height: usize) {
#[cfg(feature = "flutter_texture_render")]
if let Some(session) = SESSIONS.write().unwrap().get_mut(&_session_id) {

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", "管理的设备数已达到最大值"),
("Sync with recent sessions", "同步最近会话"),
("Sort tags", "对标签进行排序"),
("Separate remote window", "使用独立远程窗口"),
("separate window", "独立窗口"),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", "Sie haben die maximale Anzahl der verwalteten Geräte erreicht."),
("Sync with recent sessions", "Synchronisierung mit den letzten Sitzungen"),
("Sort tags", "Tags sortieren"),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", "Has alcanzado el máximo número de dispositivos administrados."),
("Sync with recent sessions", "Sincronizar con sesiones recientes"),
("Sort tags", "Ordenar etiquetas"),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", "Hai raggiunto il numero massimo di dispositivi gestibili."),
("Sync with recent sessions", "Sincronizza con le sessioni recenti"),
("Sort tags", "Ordina etichette"),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", "Het maximum aantal gecontroleerde apparaten is bereikt."),
("Sync with recent sessions", "Recente sessies synchroniseren"),
("Sort tags", "Labels sorteren"),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", "Достигнуто максимальне количество управляемых устройств."),
("Sync with recent sessions", "Синхронизация последних сессий"),
("Sort tags", "Сортировка меток"),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -524,5 +524,7 @@ pub static ref T: std::collections::HashMap<&'static str, &'static str> =
("exceed_max_devices", ""),
("Sync with recent sessions", ""),
("Sort tags", ""),
("Separate remote window", ""),
("separate window", ""),
].iter().cloned().collect();
}

View File

@@ -94,8 +94,7 @@ pub fn start(args: &mut [String]) {
args[1] = id;
}
if args.is_empty() {
let children: Children = Default::default();
std::thread::spawn(move || check_zombie(children));
std::thread::spawn(move || check_zombie());
crate::common::check_software_update();
frame.event_handler(UI {});
frame.sciter_handler(UIHostHandler {});
@@ -693,28 +692,6 @@ impl sciter::host::HostHandler for UIHostHandler {
}
}
pub fn check_zombie(children: Children) {
let mut deads = Vec::new();
loop {
let mut lock = children.lock().unwrap();
let mut n = 0;
for (id, c) in lock.1.iter_mut() {
if let Ok(Some(_)) = c.try_wait() {
deads.push(id.clone());
n += 1;
}
}
for ref id in deads.drain(..) {
lock.1.remove(id);
}
if n > 0 {
lock.0 = true;
}
drop(lock);
std::thread::sleep(std::time::Duration::from_millis(100));
}
}
#[cfg(not(target_os = "linux"))]
fn get_sound_inputs() -> Vec<String> {
let mut out = Vec::new();
@@ -748,50 +725,6 @@ pub fn value_crash_workaround(values: &[Value]) -> Arc<Vec<Value>> {
persist
}
#[inline]
pub fn new_remote(id: String, remote_type: String, force_relay: bool) {
let mut lock = CHILDREN.lock().unwrap();
let mut args = vec![format!("--{}", remote_type), id.clone()];
if force_relay {
args.push("".to_string()); // password
args.push("--relay".to_string());
}
let key = (id.clone(), remote_type.clone());
if let Some(c) = lock.1.get_mut(&key) {
if let Ok(Some(_)) = c.try_wait() {
lock.1.remove(&key);
} else {
if remote_type == "rdp" {
allow_err!(c.kill());
std::thread::sleep(std::time::Duration::from_millis(30));
c.try_wait().ok();
lock.1.remove(&key);
} else {
return;
}
}
}
match crate::run_me(args) {
Ok(child) => {
lock.1.insert(key, child);
}
Err(err) => {
log::error!("Failed to spawn remote: {}", err);
}
}
}
#[inline]
pub fn recent_sessions_updated() -> bool {
let mut children = CHILDREN.lock().unwrap();
if children.0 {
children.0 = false;
true
} else {
false
}
}
pub fn get_icon() -> String {
// 128x128
#[cfg(target_os = "macos")]

View File

@@ -65,6 +65,7 @@ lazy_static::lazy_static! {
static ref OPTION_SYNCED: Arc<Mutex<bool>> = Default::default();
static ref OPTIONS : Arc<Mutex<HashMap<String, String>>> = Arc::new(Mutex::new(Config::get_options()));
pub static ref SENDER : Mutex<mpsc::UnboundedSender<ipc::Data>> = Mutex::new(check_connect_status(true));
static ref CHILDREN : Children = Default::default();
}
const INIT_ASYNC_JOB_STATUS: &str = " ";
@@ -827,11 +828,11 @@ pub fn check_super_user_permission() -> bool {
return true;
}
#[allow(dead_code)]
pub fn check_zombie(children: Children) {
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "flutter")))]
pub fn check_zombie() {
let mut deads = Vec::new();
loop {
let mut lock = children.lock().unwrap();
let mut lock = CHILDREN.lock().unwrap();
let mut n = 0;
for (id, c) in lock.1.iter_mut() {
if let Ok(Some(_)) = c.try_wait() {
@@ -850,6 +851,51 @@ pub fn check_zombie(children: Children) {
}
}
#[inline]
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "flutter")))]
pub fn recent_sessions_updated() -> bool {
let mut children = CHILDREN.lock().unwrap();
if children.0 {
children.0 = false;
true
} else {
false
}
}
#[cfg(not(any(target_os = "android", target_os = "ios", feature = "flutter")))]
pub fn new_remote(id: String, remote_type: String, force_relay: bool) {
let mut lock = CHILDREN.lock().unwrap();
let mut args = vec![format!("--{}", remote_type), id.clone()];
if force_relay {
args.push("".to_string()); // password
args.push("--relay".to_string());
}
let key = (id.clone(), remote_type.clone());
if let Some(c) = lock.1.get_mut(&key) {
if let Ok(Some(_)) = c.try_wait() {
lock.1.remove(&key);
} else {
if remote_type == "rdp" {
allow_err!(c.kill());
std::thread::sleep(std::time::Duration::from_millis(30));
c.try_wait().ok();
lock.1.remove(&key);
} else {
return;
}
}
}
match crate::run_me(args) {
Ok(child) => {
lock.1.insert(key, child);
}
Err(err) => {
log::error!("Failed to spawn remote: {}", err);
}
}
}
// Make sure `SENDER` is inited here.
#[inline]
#[cfg(not(any(target_os = "android", target_os = "ios")))]

View File

@@ -48,6 +48,16 @@ pub static IS_IN: AtomicBool = AtomicBool::new(false);
const CHANGE_RESOLUTION_VALID_TIMEOUT_SECS: u64 = 15;
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
#[derive(Default)]
pub struct CacheFlutter {
pub pi: PeerInfo,
pub sp: Option<SwitchDisplay>,
pub cursor_data: HashMap<u64, CursorData>,
pub cursor_id: u64,
}
#[derive(Clone, Default)]
pub struct Session<T: InvokeUiSession> {
pub session_id: SessionID, // different from the one in LoginConfigHandler, used for flutter UI message pass
@@ -62,6 +72,9 @@ pub struct Session<T: InvokeUiSession> {
pub server_file_transfer_enabled: Arc<RwLock<bool>>,
pub server_clipboard_enabled: Arc<RwLock<bool>>,
pub last_change_display: Arc<Mutex<ChangeDisplayRecord>>,
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
pub cache_flutter: Arc<RwLock<CacheFlutter>>,
}
#[derive(Clone)]
@@ -1181,12 +1194,26 @@ impl<T: InvokeUiSession> Session<T> {
pub fn ctrl_alt_del(&self) {
self.send_key_event(&crate::keyboard::client::event_ctrl_alt_del());
}
#[cfg(feature = "flutter")]
#[cfg(not(any(target_os = "android", target_os = "ios")))]
pub fn restore_flutter_cache(&mut self) {
let pi = self.cache_flutter.read().unwrap().pi.clone();
self.handle_peer_info(pi);
if let Some(sp) = self.cache_flutter.read().unwrap().sp.as_ref() {
self.handle_peer_switch_display(sp);
}
for (_, cd) in self.cache_flutter.read().unwrap().cursor_data.iter() {
self.set_cursor_data(cd.clone());
}
self.set_cursor_id(self.cache_flutter.read().unwrap().cursor_id.to_string());
}
}
#[tokio::main(flavor = "current_thread")]
pub async fn io_loop<T: InvokeUiSession>(handler: Session<T>) {
// It is ok to call this function multiple times.
#[cfg(target_os ="windows")]
#[cfg(target_os = "windows")]
if !handler.is_file_transfer() && !handler.is_port_forward() {
clipboard::ContextSend::enable(true);
}