2022-10-11 19:52:03 +08:00
|
|
|
/// Url handler based on dbus
|
|
|
|
///
|
|
|
|
/// Note:
|
|
|
|
/// On linux, we use dbus to communicate multiple rustdesk process.
|
|
|
|
/// [Flutter]: handle uni links for linux
|
|
|
|
use dbus::blocking::Connection;
|
|
|
|
use dbus_crossroads::{Crossroads, IfaceBuilder};
|
2023-01-18 13:54:56 +08:00
|
|
|
use hbb_common::log;
|
2022-11-10 23:26:09 +08:00
|
|
|
#[cfg(feature = "flutter")]
|
|
|
|
use std::collections::HashMap;
|
2023-01-18 13:54:56 +08:00
|
|
|
use std::{error::Error, fmt, time::Duration};
|
2022-10-11 19:52:03 +08:00
|
|
|
|
|
|
|
const DBUS_NAME: &str = "org.rustdesk.rustdesk";
|
|
|
|
const DBUS_PREFIX: &str = "/dbus";
|
|
|
|
const DBUS_METHOD_NEW_CONNECTION: &str = "NewConnection";
|
|
|
|
const DBUS_METHOD_NEW_CONNECTION_ID: &str = "id";
|
|
|
|
const DBUS_METHOD_RETURN: &str = "ret";
|
|
|
|
const DBUS_METHOD_RETURN_SUCCESS: &str = "ok";
|
|
|
|
const DBUS_TIMEOUT: Duration = Duration::from_secs(5);
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
struct DbusError(String);
|
|
|
|
|
|
|
|
impl fmt::Display for DbusError {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
write!(f, "RustDesk DBus Error: {}", self.0)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Error for DbusError {}
|
|
|
|
|
|
|
|
/// invoke new connection from dbus
|
2023-01-18 13:54:56 +08:00
|
|
|
///
|
2022-10-11 19:52:03 +08:00
|
|
|
/// [Tips]:
|
|
|
|
/// How to test by CLI:
|
|
|
|
/// - use dbus-send command:
|
|
|
|
/// `dbus-send --session --print-reply --dest=org.rustdesk.rustdesk /dbus org.rustdesk.rustdesk.NewConnection string:'PEER_ID'`
|
2023-01-18 13:54:56 +08:00
|
|
|
pub fn invoke_new_connection(uni_links: String) -> Result<(), Box<dyn Error>> {
|
2023-06-10 18:24:03 +08:00
|
|
|
log::info!("Starting dbus service for uni");
|
2022-10-11 19:52:03 +08:00
|
|
|
let conn = Connection::new_session()?;
|
|
|
|
let proxy = conn.with_proxy(DBUS_NAME, DBUS_PREFIX, DBUS_TIMEOUT);
|
2023-01-18 13:54:56 +08:00
|
|
|
let (ret,): (String,) =
|
|
|
|
proxy.method_call(DBUS_NAME, DBUS_METHOD_NEW_CONNECTION, (uni_links,))?;
|
2022-10-11 19:52:03 +08:00
|
|
|
if ret != DBUS_METHOD_RETURN_SUCCESS {
|
|
|
|
log::error!("error on call new connection to dbus server");
|
|
|
|
return Err(Box::new(DbusError("not success".to_string())));
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
/// start dbus server
|
|
|
|
///
|
|
|
|
/// [Blocking]:
|
|
|
|
/// The function will block current thread to serve dbus server.
|
|
|
|
/// So it's suitable to spawn a new thread dedicated to dbus server.
|
|
|
|
pub fn start_dbus_server() -> Result<(), Box<dyn Error>> {
|
|
|
|
let conn: Connection = Connection::new_session()?;
|
|
|
|
let _ = conn.request_name(DBUS_NAME, false, true, false)?;
|
|
|
|
let mut cr = Crossroads::new();
|
|
|
|
let token = cr.register(DBUS_NAME, handle_client_message);
|
|
|
|
cr.insert(DBUS_PREFIX, &[token], ());
|
|
|
|
cr.serve(&conn)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn handle_client_message(builder: &mut IfaceBuilder<()>) {
|
|
|
|
// register new connection dbus
|
|
|
|
builder.method(
|
|
|
|
DBUS_METHOD_NEW_CONNECTION,
|
|
|
|
(DBUS_METHOD_NEW_CONNECTION_ID,),
|
|
|
|
(DBUS_METHOD_RETURN,),
|
2023-01-18 13:54:56 +08:00
|
|
|
move |_, _, (_uni_links,): (String,)| {
|
2022-10-11 19:52:03 +08:00
|
|
|
#[cfg(feature = "flutter")]
|
|
|
|
{
|
2023-04-19 11:34:52 +08:00
|
|
|
use crate::flutter;
|
2023-04-18 23:02:37 +08:00
|
|
|
let data = HashMap::from([
|
2023-06-10 18:24:03 +08:00
|
|
|
("name", "on_url_scheme_received"),
|
|
|
|
("url", _uni_links.as_str()),
|
2023-04-18 23:02:37 +08:00
|
|
|
]);
|
|
|
|
let event = serde_json::ser::to_string(&data).unwrap_or("".to_string());
|
|
|
|
match crate::flutter::push_global_event(flutter::APP_TYPE_MAIN, event) {
|
|
|
|
None => log::error!("failed to find main event stream"),
|
|
|
|
Some(false) => {
|
|
|
|
log::error!("failed to add dbus message to flutter global dbus stream.")
|
2022-10-11 19:52:03 +08:00
|
|
|
}
|
2023-04-18 23:02:37 +08:00
|
|
|
Some(true) => {}
|
2022-10-11 19:52:03 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return Ok((DBUS_METHOD_RETURN_SUCCESS.to_string(),));
|
|
|
|
},
|
|
|
|
);
|
|
|
|
}
|