diff --git a/src/flutter_ffi.rs b/src/flutter_ffi.rs index d2a0eddef..71cedb0a8 100644 --- a/src/flutter_ffi.rs +++ b/src/flutter_ffi.rs @@ -1,6 +1,7 @@ use crate::client::file_trait::FileManager; use crate::flutter::connection_manager::{self, get_clients_length, get_clients_state}; use crate::flutter::{self, make_fd_to_json, Session}; +use crate::ui; use flutter_rust_bridge::{StreamSink, ZeroCopyBuffer}; use hbb_common::ResultType; use hbb_common::{ @@ -115,7 +116,7 @@ unsafe extern "C" fn get_by_name(name: *const c_char, arg: *const c_char) -> *co } } "server_id" => { - res = Config::get_id(); + res = ui::get_id(); } "server_password" => { res = Config::get_password(); @@ -296,7 +297,11 @@ unsafe extern "C" fn set_by_name(name: *const c_char, value: *const c_char) { if name == "custom-rendezvous-server" { #[cfg(target_os = "android")] crate::rendezvous_mediator::RendezvousMediator::restart(); - #[cfg(any(target_os = "android", target_os = "ios", feature = "cli"))] + #[cfg(any( + target_os = "android", + target_os = "ios", + feature = "cli" + ))] crate::common::test_rendezvous_server(); } } diff --git a/src/ui.rs b/src/ui.rs index 5e133ea79..c734d7555 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -23,25 +23,595 @@ use std::{ iter::FromIterator, process::Child, sync::{Arc, Mutex}, + time::SystemTime, }; type Message = RendezvousMessage; pub type Childs = Arc)>>; -type Status = (i32, bool, i64, String); +type Status = (i32, bool, i64, String); // (status_num, key_confirmed, mouse_time, id) lazy_static::lazy_static! { // stupid workaround for https://sciter.com/forums/topic/crash-on-latest-tis-mac-sdk-sometimes/ static ref STUPID_VALUES: Mutex>>> = Default::default(); + pub static ref CHILDS : Childs = Default::default(); + pub static ref UI_STATUS : Arc> = Arc::new(Mutex::new((0, false, 0, "".to_owned()))); + pub static ref OPTIONS : Arc>> = Arc::new(Mutex::new(Config::get_options())); + pub static ref ASYNC_JOB_STATUS : Arc> = Default::default(); + pub static ref SENDER : Mutex> = Mutex::new(check_connect_status(true)); } -struct UI( - Childs, - Arc>, - Arc>>, - Arc>, - mpsc::UnboundedSender, -); +// struct UI( +// Childs, +// Arc>, +// Arc>>, options +// Arc>, async_job_status +// mpsc::UnboundedSender, Sender +// ); + +pub fn recent_sessions_updated() -> bool { + let mut childs = CHILDS.lock().unwrap(); + if childs.0 { + childs.0 = false; + true + } else { + false + } +} + +pub fn get_id() -> String { + ipc::get_id() +} + +pub fn get_password() -> String { + ipc::get_password() +} + +pub fn update_password(password: String) { + if password.is_empty() { + allow_err!(ipc::set_password(Config::get_auto_password())); + } else { + allow_err!(ipc::set_password(password)); + } +} + +pub fn get_remote_id() -> String { + LocalConfig::get_remote_id() +} + +pub fn set_remote_id(id: String) { + LocalConfig::set_remote_id(&id); +} + +pub fn goto_install() { + allow_err!(crate::run_me(vec!["--install"])); +} + +pub fn install_me(_options: String, _path: String) { + #[cfg(windows)] + std::thread::spawn(move || { + allow_err!(crate::platform::windows::install_me(&_options, _path)); + std::process::exit(0); + }); +} + +pub fn update_me(_path: String) { + #[cfg(target_os = "linux")] + { + std::process::Command::new("pkexec") + .args(&["apt", "install", "-f", &_path]) + .spawn() + .ok(); + std::fs::remove_file(&_path).ok(); + crate::run_me(Vec::<&str>::new()).ok(); + } + #[cfg(windows)] + { + let mut path = _path; + if path.is_empty() { + if let Ok(tmp) = std::env::current_exe() { + path = tmp.to_string_lossy().to_string(); + } + } + std::process::Command::new(path) + .arg("--update") + .spawn() + .ok(); + std::process::exit(0); + } +} + +pub fn run_without_install() { + crate::run_me(vec!["--noinstall"]).ok(); + std::process::exit(0); +} + +pub fn show_run_without_install() -> bool { + let mut it = std::env::args(); + if let Some(tmp) = it.next() { + if crate::is_setup(&tmp) { + return it.next() == None; + } + } + false +} + +pub fn has_rendezvous_service() -> bool { + #[cfg(all(windows, feature = "hbbs"))] + return crate::platform::is_win_server() && crate::platform::windows::get_license().is_some(); + return false; +} + +pub fn get_license() -> String { + #[cfg(windows)] + if let Some(lic) = crate::platform::windows::get_license() { + return format!( + "
Key: {}
Host: {} Api: {}", + lic.key, lic.host, lic.api + ); + } + Default::default() +} + +pub fn get_option(key: String) -> String { + get_option_(&key) +} + +fn get_option_(key: &str) -> String { + let map = OPTIONS.lock().unwrap(); + if let Some(v) = map.get(key) { + v.to_owned() + } else { + "".to_owned() + } +} + +pub fn get_local_option(key: String) -> String { + LocalConfig::get_option(&key) +} + +pub fn set_local_option(key: String, value: String) { + LocalConfig::set_option(key, value); +} + +pub fn peer_has_password(id: String) -> bool { + !PeerConfig::load(&id).password.is_empty() +} + +pub fn forget_password(id: String) { + let mut c = PeerConfig::load(&id); + c.password.clear(); + c.store(&id); +} + +pub fn get_peer_option(id: String, name: String) -> String { + let c = PeerConfig::load(&id); + c.options.get(&name).unwrap_or(&"".to_owned()).to_owned() +} + +pub fn set_peer_option(id: String, name: String, value: String) { + let mut c = PeerConfig::load(&id); + if value.is_empty() { + c.options.remove(&name); + } else { + c.options.insert(name, value); + } + c.store(&id); +} + +pub fn using_public_server() -> bool { + crate::get_custom_rendezvous_server(get_option_("custom-rendezvous-server")).is_empty() +} + +pub fn get_options() -> HashMap { + // TODO Vec<(String,String)> + let options = OPTIONS.lock().unwrap(); + let mut m = HashMap::new(); + for (k, v) in options.iter() { + m.insert(k.into(), v.into()); + } + m +} + +pub fn test_if_valid_server(host: String) -> String { + hbb_common::socket_client::test_if_valid_server(&host) +} + +pub fn get_sound_inputs() -> Vec { + let mut a = Vec::new(); + #[cfg(windows)] + { + // TODO TEST + fn get_sound_inputs_() -> Vec { + let mut out = Vec::new(); + use cpal::traits::{DeviceTrait, HostTrait}; + let host = cpal::default_host(); + if let Ok(devices) = host.devices() { + for device in devices { + if device.default_input_config().is_err() { + continue; + } + if let Ok(name) = device.name() { + out.push(name); + } + } + } + out + } + + let inputs = Arc::new(Mutex::new(Vec::new())); + let cloned = inputs.clone(); + // can not call below in UI thread, because conflict with sciter sound com initialization + std::thread::spawn(move || *cloned.lock().unwrap() = get_sound_inputs_()) + .join() + .ok(); + for name in inputs.lock().unwrap().drain(..) { + a.push(name); + } + } + #[cfg(not(windows))] + { + let inputs: Vec = crate::platform::linux::get_pa_sources() + .drain(..) + .map(|x| x.1) + .collect(); + + for name in inputs { + a.push(name); + } + } + a +} + +pub fn set_options(m: HashMap) { + *OPTIONS.lock().unwrap() = m.clone(); + ipc::set_options(m).ok(); +} + +pub fn set_option(key: String, value: String) { + let mut options = OPTIONS.lock().unwrap(); + #[cfg(target_os = "macos")] + if &key == "stop-service" { + let is_stop = value == "Y"; + if is_stop && crate::platform::macos::uninstall() { + return; + } + } + if value.is_empty() { + options.remove(&key); + } else { + options.insert(key.clone(), value.clone()); + } + ipc::set_options(options.clone()).ok(); +} + +pub fn install_path() -> String { + #[cfg(windows)] + return crate::platform::windows::get_install_info().1; + #[cfg(not(windows))] + return "".to_owned(); +} + +pub fn get_socks() -> Vec { + let s = ipc::get_socks(); + match s { + None => Vec::new(), + Some(s) => { + let mut v = Vec::new(); + v.push(s.proxy); + v.push(s.username); + v.push(s.password); + v + } + } +} + +pub fn set_socks(proxy: String, username: String, password: String) { + ipc::set_socks(config::Socks5Server { + proxy, + username, + password, + }) + .ok(); +} + +pub fn is_installed() -> bool { + crate::platform::is_installed() +} + +pub fn is_rdp_service_open() -> bool { + #[cfg(windows)] + return is_installed() && crate::platform::windows::is_rdp_service_open(); + #[cfg(not(windows))] + return false; +} + +pub fn is_share_rdp() -> bool { + #[cfg(windows)] + return crate::platform::windows::is_share_rdp(); + #[cfg(not(windows))] + return false; +} + +pub fn set_share_rdp(_enable: bool) { + #[cfg(windows)] + crate::platform::windows::set_share_rdp(_enable); +} + +pub fn is_installed_lower_version() -> bool { + #[cfg(not(windows))] + return false; + #[cfg(windows)] + { + let installed_version = crate::platform::windows::get_installed_version(); + let a = hbb_common::get_version_number(crate::VERSION); + let b = hbb_common::get_version_number(&installed_version); + return a > b; + } +} + +pub fn closing(x: i32, y: i32, w: i32, h: i32) { + crate::server::input_service::fix_key_down_timeout_at_exit(); + LocalConfig::set_size(x, y, w, h); +} + +pub fn get_size() -> Vec { + let s = LocalConfig::get_size(); + let mut v = Vec::new(); + v.push(s.0); + v.push(s.1); + v.push(s.2); + v.push(s.3); + v +} + +pub fn get_mouse_time() -> f64 { + let ui_status = UI_STATUS.lock().unwrap(); + let res = ui_status.2 as f64; + return res; +} + +pub fn check_mouse_time() { + let sender = SENDER.lock().unwrap(); + allow_err!(sender.send(ipc::Data::MouseMoveTime(0))); +} + +pub fn get_connect_status() -> Status { + let ui_statue = UI_STATUS.lock().unwrap(); + let res = ui_statue.clone(); + res +} + +pub fn get_peer(id: String) -> PeerConfig { + PeerConfig::load(&id) +} + +pub fn get_fav() -> Vec { + LocalConfig::get_fav() +} + +pub fn store_fav(fav: Vec) { + LocalConfig::set_fav(fav); +} + +pub fn get_recent_sessions() -> Vec<(String, SystemTime, PeerConfig)> { + PeerConfig::peers() +} + +pub fn get_icon() -> String { + crate::get_icon() +} + +pub fn remove_peer(id: String) { + PeerConfig::remove(&id); +} + +pub fn new_remote(id: String, remote_type: String) { + let mut lock = CHILDS.lock().unwrap(); + let args = vec![format!("--{}", remote_type), id.clone()]; + 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); + } + } +} + +pub fn is_process_trusted(_prompt: bool) -> bool { + #[cfg(target_os = "macos")] + return crate::platform::macos::is_process_trusted(_prompt); + #[cfg(not(target_os = "macos"))] + return true; +} + +pub fn is_can_screen_recording(_prompt: bool) -> bool { + #[cfg(target_os = "macos")] + return crate::platform::macos::is_can_screen_recording(_prompt); + #[cfg(not(target_os = "macos"))] + return true; +} + +pub fn is_installed_daemon(_prompt: bool) -> bool { + #[cfg(target_os = "macos")] + return crate::platform::macos::is_installed_daemon(_prompt); + #[cfg(not(target_os = "macos"))] + return true; +} + +pub fn get_error() -> String { + #[cfg(target_os = "linux")] + { + let dtype = crate::platform::linux::get_display_server(); + if "wayland" == dtype { + return "".to_owned(); + } + if dtype != "x11" { + return format!( + "{} {}, {}", + t("Unsupported display server ".to_owned()), + dtype, + t("x11 expected".to_owned()), + ); + } + } + return "".to_owned(); +} + +pub fn is_login_wayland() -> bool { + #[cfg(target_os = "linux")] + return crate::platform::linux::is_login_wayland(); + #[cfg(not(target_os = "linux"))] + return false; +} + +pub fn fix_login_wayland() { + #[cfg(target_os = "linux")] + crate::platform::linux::fix_login_wayland(); +} + +pub fn current_is_wayland() -> bool { + #[cfg(target_os = "linux")] + return crate::platform::linux::current_is_wayland(); + #[cfg(not(target_os = "linux"))] + return false; +} + +pub fn modify_default_login() -> String { + #[cfg(target_os = "linux")] + return crate::platform::linux::modify_default_login(); + #[cfg(not(target_os = "linux"))] + return "".to_owned(); +} + +pub fn get_software_update_url() -> String { + SOFTWARE_UPDATE_URL.lock().unwrap().clone() +} + +pub fn get_new_version() -> String { + hbb_common::get_version_from_url(&*SOFTWARE_UPDATE_URL.lock().unwrap()) +} + +pub fn get_version() -> String { + crate::VERSION.to_owned() +} + +pub fn get_app_name() -> String { + crate::get_app_name() +} + +pub fn get_software_ext() -> String { + #[cfg(windows)] + let p = "exe"; + #[cfg(target_os = "macos")] + let p = "dmg"; + #[cfg(target_os = "linux")] + let p = "deb"; + p.to_owned() +} + +pub fn get_software_store_path() -> String { + let mut p = std::env::temp_dir(); + let name = SOFTWARE_UPDATE_URL + .lock() + .unwrap() + .split("/") + .last() + .map(|x| x.to_owned()) + .unwrap_or(crate::get_app_name()); + p.push(name); + format!("{}.{}", p.to_string_lossy(), get_software_ext()) +} + +pub fn create_shortcut(_id: String) { + #[cfg(windows)] + crate::platform::windows::create_shortcut(&_id).ok(); +} + +pub fn discover() { + std::thread::spawn(move || { + allow_err!(crate::rendezvous_mediator::discover()); + }); +} + +pub fn get_lan_peers() -> String { + config::LanPeers::load().peers +} + +pub fn get_uuid() -> String { + base64::encode(crate::get_uuid()) +} + +pub fn open_url(url: String) { + #[cfg(windows)] + let p = "explorer"; + #[cfg(target_os = "macos")] + let p = "open"; + #[cfg(target_os = "linux")] + let p = if std::path::Path::new("/usr/bin/firefox").exists() { + "firefox" + } else { + "xdg-open" + }; + allow_err!(std::process::Command::new(p).arg(url).spawn()); +} + +pub fn change_id(id: String) { + *ASYNC_JOB_STATUS.lock().unwrap() = " ".to_owned(); + let old_id = get_id(); + std::thread::spawn(move || { + *ASYNC_JOB_STATUS.lock().unwrap() = change_id_(id, old_id).to_owned(); + }); +} + +pub fn post_request(url: String, body: String, header: String) { + *ASYNC_JOB_STATUS.lock().unwrap() = " ".to_owned(); + std::thread::spawn(move || { + *ASYNC_JOB_STATUS.lock().unwrap() = match crate::post_request_sync(url, body, &header) { + Err(err) => err.to_string(), + Ok(text) => text, + }; + }); +} + +pub fn is_ok_change_id() -> bool { + machine_uid::get().is_ok() +} + +pub fn get_async_job_status() -> String { + ASYNC_JOB_STATUS.lock().unwrap().clone() +} + +pub fn t(name: String) -> String { + crate::client::translate(name) +} + +pub fn is_xfce() -> bool { + crate::platform::is_xfce() +} + +pub fn get_api_server() -> String { + crate::get_api_server( + get_option_("api-server"), + get_option_("custom-rendezvous-server"), + ) +} struct UIHostHandler; @@ -67,7 +637,7 @@ pub fn start(args: &mut [String]) { } #[cfg(windows)] if args.len() > 0 && args[0] == "--tray" { - let options = check_connect_status(false).1; + let options = OPTIONS.clone(); crate::tray::start_tray(options); return; } @@ -93,16 +663,14 @@ pub fn start(args: &mut [String]) { args[1] = id; } if args.is_empty() { - let childs: Childs = Default::default(); - let cloned = childs.clone(); + let cloned = CHILDS.clone(); std::thread::spawn(move || check_zombie(cloned)); crate::common::check_software_update(); - frame.event_handler(UI::new(childs)); + frame.event_handler(UI {}); frame.sciter_handler(UIHostHandler {}); page = "index.html"; } else if args[0] == "--install" { - let childs: Childs = Default::default(); - frame.event_handler(UI::new(childs)); + frame.event_handler(UI {}); frame.sciter_handler(UIHostHandler {}); page = "install.html"; } else if args[0] == "--cm" { @@ -158,197 +726,108 @@ pub fn start(args: &mut [String]) { frame.run_app(); } -impl UI { - fn new(childs: Childs) -> Self { - let res = check_connect_status(true); - Self(childs, res.0, res.1, Default::default(), res.2) - } +struct UI {} - fn recent_sessions_updated(&mut self) -> bool { - let mut lock = self.0.lock().unwrap(); - if lock.0 { - lock.0 = false; - true - } else { - false - } +impl UI { + fn recent_sessions_updated(&self) -> bool { + recent_sessions_updated() } fn get_id(&self) -> String { - ipc::get_id() + get_id() } fn get_password(&mut self) -> String { - ipc::get_password() + get_password() } fn update_password(&mut self, password: String) { - if password.is_empty() { - allow_err!(ipc::set_password(Config::get_auto_password())); - } else { - allow_err!(ipc::set_password(password)); - } + update_password(password) } fn get_remote_id(&mut self) -> String { - LocalConfig::get_remote_id() + get_remote_id() } fn set_remote_id(&mut self, id: String) { - LocalConfig::set_remote_id(&id); + set_remote_id(id); } fn goto_install(&mut self) { - allow_err!(crate::run_me(vec!["--install"])); + goto_install(); } fn install_me(&mut self, _options: String, _path: String) { - #[cfg(windows)] - std::thread::spawn(move || { - allow_err!(crate::platform::windows::install_me(&_options, _path)); - std::process::exit(0); - }); + install_me(_options, _path); } fn update_me(&self, _path: String) { - #[cfg(target_os = "linux")] - { - std::process::Command::new("pkexec") - .args(&["apt", "install", "-f", &_path]) - .spawn() - .ok(); - std::fs::remove_file(&_path).ok(); - crate::run_me(Vec::<&str>::new()).ok(); - } - #[cfg(windows)] - { - let mut path = _path; - if path.is_empty() { - if let Ok(tmp) = std::env::current_exe() { - path = tmp.to_string_lossy().to_string(); - } - } - std::process::Command::new(path) - .arg("--update") - .spawn() - .ok(); - std::process::exit(0); - } + update_me(_path); } fn run_without_install(&self) { - crate::run_me(vec!["--noinstall"]).ok(); - std::process::exit(0); + run_without_install(); } fn show_run_without_install(&self) -> bool { - let mut it = std::env::args(); - if let Some(tmp) = it.next() { - if crate::is_setup(&tmp) { - return it.next() == None; - } - } - false + show_run_without_install() } fn has_rendezvous_service(&self) -> bool { - #[cfg(all(windows, feature = "hbbs"))] - return crate::platform::is_win_server() - && crate::platform::windows::get_license().is_some(); - return false; + has_rendezvous_service() } fn get_license(&self) -> String { - #[cfg(windows)] - if let Some(lic) = crate::platform::windows::get_license() { - return format!( - "
Key: {}
Host: {} Api: {}", - lic.key, lic.host, lic.api - ); - } - Default::default() + get_license() } fn get_option(&self, key: String) -> String { - self.get_option_(&key) - } - - fn get_option_(&self, key: &str) -> String { - if let Some(v) = self.2.lock().unwrap().get(key) { - v.to_owned() - } else { - "".to_owned() - } + get_option(key) } fn get_local_option(&self, key: String) -> String { - LocalConfig::get_option(&key) + get_local_option(key) } fn set_local_option(&self, key: String, value: String) { - LocalConfig::set_option(key, value); + set_local_option(key, value); } fn peer_has_password(&self, id: String) -> bool { - !PeerConfig::load(&id).password.is_empty() + peer_has_password(id) } fn forget_password(&self, id: String) { - let mut c = PeerConfig::load(&id); - c.password.clear(); - c.store(&id); + forget_password(id) } fn get_peer_option(&self, id: String, name: String) -> String { - let c = PeerConfig::load(&id); - c.options.get(&name).unwrap_or(&"".to_owned()).to_owned() + get_peer_option(id, name) } fn set_peer_option(&self, id: String, name: String, value: String) { - let mut c = PeerConfig::load(&id); - if value.is_empty() { - c.options.remove(&name); - } else { - c.options.insert(name, value); - } - c.store(&id); + set_peer_option(id, name, value) } fn using_public_server(&self) -> bool { - crate::get_custom_rendezvous_server(self.get_option_("custom-rendezvous-server")).is_empty() + using_public_server() } fn get_options(&self) -> Value { + let hashmap = get_options(); let mut m = Value::map(); - for (k, v) in self.2.lock().unwrap().iter() { + for (k, v) in hashmap { m.set_item(k, v); } m } fn test_if_valid_server(&self, host: String) -> String { - hbb_common::socket_client::test_if_valid_server(&host) + test_if_valid_server(host) } fn get_sound_inputs(&self) -> Value { - let mut a = Value::array(0); - #[cfg(windows)] - { - let inputs = Arc::new(Mutex::new(Vec::new())); - let cloned = inputs.clone(); - // can not call below in UI thread, because conflict with sciter sound com initialization - std::thread::spawn(move || *cloned.lock().unwrap() = get_sound_inputs()) - .join() - .ok(); - for name in inputs.lock().unwrap().drain(..) { - a.push(name); - } - } - #[cfg(not(windows))] - for name in get_sound_inputs() { - a.push(name); - } - a + Value::from_iter(get_sound_inputs()) } fn set_options(&self, v: Value) { @@ -362,119 +841,64 @@ impl UI { } } } - - *self.2.lock().unwrap() = m.clone(); - ipc::set_options(m).ok(); + set_options(m); } fn set_option(&self, key: String, value: String) { - #[cfg(target_os = "macos")] - if &key == "stop-service" { - let is_stop = value == "Y"; - if is_stop && crate::platform::macos::uninstall() { - return; - } - } - let mut options = self.2.lock().unwrap(); - if value.is_empty() { - options.remove(&key); - } else { - options.insert(key.clone(), value.clone()); - } - ipc::set_options(options.clone()).ok(); + set_option(key, value); } fn install_path(&mut self) -> String { - #[cfg(windows)] - return crate::platform::windows::get_install_info().1; - #[cfg(not(windows))] - return "".to_owned(); + install_path() } fn get_socks(&self) -> Value { - let s = ipc::get_socks(); - match s { - None => Value::null(), - Some(s) => { - let mut v = Value::array(0); - v.push(s.proxy); - v.push(s.username); - v.push(s.password); - v - } - } + Value::from_iter(get_socks()) } fn set_socks(&self, proxy: String, username: String, password: String) { - ipc::set_socks(config::Socks5Server { - proxy, - username, - password, - }) - .ok(); + set_socks(proxy, username, password) } fn is_installed(&self) -> bool { - crate::platform::is_installed() + is_installed() } fn is_rdp_service_open(&self) -> bool { - #[cfg(windows)] - return self.is_installed() && crate::platform::windows::is_rdp_service_open(); - #[cfg(not(windows))] - return false; + is_rdp_service_open() } fn is_share_rdp(&self) -> bool { - #[cfg(windows)] - return crate::platform::windows::is_share_rdp(); - #[cfg(not(windows))] - return false; + is_share_rdp() } fn set_share_rdp(&self, _enable: bool) { - #[cfg(windows)] - crate::platform::windows::set_share_rdp(_enable); + set_share_rdp(_enable); } fn is_installed_lower_version(&self) -> bool { - #[cfg(not(windows))] - return false; - #[cfg(windows)] - { - let installed_version = crate::platform::windows::get_installed_version(); - let a = hbb_common::get_version_number(crate::VERSION); - let b = hbb_common::get_version_number(&installed_version); - return a > b; - } + is_installed_lower_version() } fn closing(&mut self, x: i32, y: i32, w: i32, h: i32) { - crate::server::input_service::fix_key_down_timeout_at_exit(); - LocalConfig::set_size(x, y, w, h); + closing(x, y, w, h) } fn get_size(&mut self) -> Value { - let s = LocalConfig::get_size(); - let mut v = Value::array(0); - v.push(s.0); - v.push(s.1); - v.push(s.2); - v.push(s.3); - v + Value::from_iter(get_size()) } fn get_mouse_time(&self) -> f64 { - self.1.lock().unwrap().2 as _ + get_mouse_time() } fn check_mouse_time(&self) { - allow_err!(self.4.send(ipc::Data::MouseMoveTime(0))); + check_mouse_time() } fn get_connect_status(&mut self) -> Value { let mut v = Value::array(0); - let x = self.1.lock().unwrap().clone(); + let x = get_connect_status(); v.push(x.0); v.push(x.1); v.push(x.3); @@ -494,12 +918,12 @@ impl UI { } fn get_peer(&self, id: String) -> Value { - let c = PeerConfig::load(&id); + let c = get_peer(id.clone()); Self::get_peer_value(id, c) } fn get_fav(&self) -> Value { - Value::from_iter(LocalConfig::get_fav()) + Value::from_iter(get_fav()) } fn store_fav(&self, fav: Value) { @@ -511,12 +935,12 @@ impl UI { } } }); - LocalConfig::set_fav(tmp); + store_fav(tmp); } fn get_recent_sessions(&mut self) -> Value { // to-do: limit number of recent sessions, and remove old peer file - let peers: Vec = PeerConfig::peers() + let peers: Vec = get_recent_sessions() .drain(..) .map(|p| Self::get_peer_value(p.0, p.2)) .collect(); @@ -524,220 +948,119 @@ impl UI { } fn get_icon(&mut self) -> String { - crate::get_icon() + get_icon() } fn remove_peer(&mut self, id: String) { - PeerConfig::remove(&id); + remove_peer(id) } fn new_remote(&mut self, id: String, remote_type: String) { - let mut lock = self.0.lock().unwrap(); - let args = vec![format!("--{}", remote_type), id.clone()]; - 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); - } - } + new_remote(id, remote_type) } fn is_process_trusted(&mut self, _prompt: bool) -> bool { - #[cfg(target_os = "macos")] - return crate::platform::macos::is_process_trusted(_prompt); - #[cfg(not(target_os = "macos"))] - return true; + is_process_trusted(_prompt) } fn is_can_screen_recording(&mut self, _prompt: bool) -> bool { - #[cfg(target_os = "macos")] - return crate::platform::macos::is_can_screen_recording(_prompt); - #[cfg(not(target_os = "macos"))] - return true; + is_can_screen_recording(_prompt) } fn is_installed_daemon(&mut self, _prompt: bool) -> bool { - #[cfg(target_os = "macos")] - return crate::platform::macos::is_installed_daemon(_prompt); - #[cfg(not(target_os = "macos"))] - return true; + is_installed_daemon(_prompt) } fn get_error(&mut self) -> String { - #[cfg(target_os = "linux")] - { - let dtype = crate::platform::linux::get_display_server(); - if "wayland" == dtype { - return "".to_owned(); - } - if dtype != "x11" { - return format!( - "{} {}, {}", - self.t("Unsupported display server ".to_owned()), - dtype, - self.t("x11 expected".to_owned()), - ); - } - } - return "".to_owned(); + get_error() } fn is_login_wayland(&mut self) -> bool { - #[cfg(target_os = "linux")] - return crate::platform::linux::is_login_wayland(); - #[cfg(not(target_os = "linux"))] - return false; + is_login_wayland() } fn fix_login_wayland(&mut self) { - #[cfg(target_os = "linux")] - crate::platform::linux::fix_login_wayland(); + fix_login_wayland() } fn current_is_wayland(&mut self) -> bool { - #[cfg(target_os = "linux")] - return crate::platform::linux::current_is_wayland(); - #[cfg(not(target_os = "linux"))] - return false; + current_is_wayland() } fn modify_default_login(&mut self) -> String { - #[cfg(target_os = "linux")] - return crate::platform::linux::modify_default_login(); - #[cfg(not(target_os = "linux"))] - return "".to_owned(); + modify_default_login() } fn get_software_update_url(&self) -> String { - SOFTWARE_UPDATE_URL.lock().unwrap().clone() + get_software_update_url() } fn get_new_version(&self) -> String { - hbb_common::get_version_from_url(&*SOFTWARE_UPDATE_URL.lock().unwrap()) + get_new_version() } fn get_version(&self) -> String { - crate::VERSION.to_owned() + get_version() } fn get_app_name(&self) -> String { - crate::get_app_name() + get_app_name() } fn get_software_ext(&self) -> String { - #[cfg(windows)] - let p = "exe"; - #[cfg(target_os = "macos")] - let p = "dmg"; - #[cfg(target_os = "linux")] - let p = "deb"; - p.to_owned() + get_software_ext() } fn get_software_store_path(&self) -> String { - let mut p = std::env::temp_dir(); - let name = SOFTWARE_UPDATE_URL - .lock() - .unwrap() - .split("/") - .last() - .map(|x| x.to_owned()) - .unwrap_or(crate::get_app_name()); - p.push(name); - format!("{}.{}", p.to_string_lossy(), self.get_software_ext()) + get_software_store_path() } fn create_shortcut(&self, _id: String) { - #[cfg(windows)] - crate::platform::windows::create_shortcut(&_id).ok(); + create_shortcut(_id) } fn discover(&self) { - std::thread::spawn(move || { - allow_err!(crate::rendezvous_mediator::discover()); - }); + discover() } fn get_lan_peers(&self) -> String { - config::LanPeers::load().peers + get_lan_peers() } fn get_uuid(&self) -> String { - base64::encode(crate::get_uuid()) + get_uuid() } fn open_url(&self, url: String) { - #[cfg(windows)] - let p = "explorer"; - #[cfg(target_os = "macos")] - let p = "open"; - #[cfg(target_os = "linux")] - let p = if std::path::Path::new("/usr/bin/firefox").exists() { - "firefox" - } else { - "xdg-open" - }; - allow_err!(std::process::Command::new(p).arg(url).spawn()); + open_url(url) } fn change_id(&self, id: String) { - let status = self.3.clone(); - *status.lock().unwrap() = " ".to_owned(); - let old_id = self.get_id(); - std::thread::spawn(move || { - *status.lock().unwrap() = change_id(id, old_id).to_owned(); - }); + change_id(id) } fn post_request(&self, url: String, body: String, header: String) { - let status = self.3.clone(); - *status.lock().unwrap() = " ".to_owned(); - std::thread::spawn(move || { - *status.lock().unwrap() = match crate::post_request_sync(url, body, &header) { - Err(err) => err.to_string(), - Ok(text) => text, - }; - }); + post_request(url, body, header) } fn is_ok_change_id(&self) -> bool { - machine_uid::get().is_ok() + is_ok_change_id() } fn get_async_job_status(&self) -> String { - self.3.clone().lock().unwrap().clone() + get_async_job_status() } fn t(&self, name: String) -> String { - crate::client::translate(name) + t(name) } fn is_xfce(&self) -> bool { - crate::platform::is_xfce() + is_xfce() } fn get_api_server(&self) -> String { - crate::get_api_server( - self.get_option_("api-server"), - self.get_option_("custom-rendezvous-server"), - ) + get_api_server() } } @@ -849,12 +1172,7 @@ pub fn check_zombie(childs: Childs) { // notice: avoiding create ipc connecton repeatly, // because windows named pipe has serious memory leak issue. #[tokio::main(flavor = "current_thread")] -async fn check_connect_status_( - reconnect: bool, - status: Arc>, - options: Arc>>, - rx: mpsc::UnboundedReceiver, -) { +async fn check_connect_status_(reconnect: bool, rx: mpsc::UnboundedReceiver) { let mut key_confirmed = false; let mut rx = rx; let mut mouse_time = 0; @@ -872,10 +1190,10 @@ async fn check_connect_status_( } Ok(Some(ipc::Data::MouseMoveTime(v))) => { mouse_time = v; - status.lock().unwrap().2 = v; + UI_STATUS.lock().unwrap().2 = v; } Ok(Some(ipc::Data::Options(Some(v)))) => { - *options.lock().unwrap() = v + *OPTIONS.lock().unwrap() = v } Ok(Some(ipc::Data::Config((name, Some(value))))) => { if name == "id" { @@ -887,7 +1205,7 @@ async fn check_connect_status_( x = 1 } key_confirmed = c; - *status.lock().unwrap() = (x as _, key_confirmed, mouse_time, id.clone()); + *UI_STATUS.lock().unwrap() = (x as _, key_confirmed, mouse_time, id.clone()); } _ => {} } @@ -904,64 +1222,28 @@ async fn check_connect_status_( } } if !reconnect { - options + OPTIONS .lock() .unwrap() .insert("ipc-closed".to_owned(), "Y".to_owned()); break; } - *status.lock().unwrap() = (-1, key_confirmed, mouse_time, id.clone()); + *UI_STATUS.lock().unwrap() = (-1, key_confirmed, mouse_time, id.clone()); sleep(1.).await; } } -#[cfg(not(target_os = "linux"))] -fn get_sound_inputs() -> Vec { - let mut out = Vec::new(); - use cpal::traits::{DeviceTrait, HostTrait}; - let host = cpal::default_host(); - if let Ok(devices) = host.devices() { - for device in devices { - if device.default_input_config().is_err() { - continue; - } - if let Ok(name) = device.name() { - out.push(name); - } - } - } - out -} - -#[cfg(target_os = "linux")] -fn get_sound_inputs() -> Vec { - crate::platform::linux::get_pa_sources() - .drain(..) - .map(|x| x.1) - .collect() -} - -fn check_connect_status( - reconnect: bool, -) -> ( - Arc>, - Arc>>, - mpsc::UnboundedSender, -) { - let status = Arc::new(Mutex::new((0, false, 0, "".to_owned()))); - let options = Arc::new(Mutex::new(Config::get_options())); - let cloned = status.clone(); - let cloned_options = options.clone(); +fn check_connect_status(reconnect: bool) -> mpsc::UnboundedSender { let (tx, rx) = mpsc::unbounded_channel::(); - std::thread::spawn(move || check_connect_status_(reconnect, cloned, cloned_options, rx)); - (status, options, tx) + std::thread::spawn(move || check_connect_status_(reconnect, rx)); + tx } const INVALID_FORMAT: &'static str = "Invalid format"; const UNKNOWN_ERROR: &'static str = "Unknown error"; #[tokio::main(flavor = "current_thread")] -async fn change_id(id: String, old_id: String) -> &'static str { +async fn change_id_(id: String, old_id: String) -> &'static str { if !hbb_common::is_valid_custom_id(&id) { return INVALID_FORMAT; }