2022-07-01 11:26:32 +08:00
use std ::{
collections ::HashMap ,
ffi ::{ CStr , CString } ,
os ::raw ::c_char ,
} ;
2022-05-31 17:36:36 +08:00
use flutter_rust_bridge ::{ StreamSink , SyncReturn , ZeroCopyBuffer } ;
2022-09-05 10:27:33 +08:00
use serde_json ::json ;
2022-07-01 11:26:32 +08:00
2022-05-12 17:35:25 +08:00
use hbb_common ::{
2022-09-05 10:27:33 +08:00
config ::{ self , LocalConfig , PeerConfig , ONLINE } ,
2022-05-12 17:35:25 +08:00
fs , log ,
} ;
2022-09-21 21:20:19 +08:00
use hbb_common ::{ message_proto ::Hash , ResultType } ;
2022-07-01 11:26:32 +08:00
2022-08-31 20:46:30 +08:00
use crate ::flutter ::{ self , SESSIONS } ;
2022-07-01 11:26:32 +08:00
use crate ::start_server ;
2022-09-27 15:32:27 +08:00
use crate ::ui_interface ::{ self , * } ;
2022-09-05 10:27:33 +08:00
use crate ::{
client ::file_trait ::FileManager ,
flutter ::{ make_fd_to_json , session_add , session_start_ } ,
} ;
2022-05-12 17:35:25 +08:00
fn initialize ( app_dir : & str ) {
* config ::APP_DIR . write ( ) . unwrap ( ) = app_dir . to_owned ( ) ;
#[ cfg(target_os = " android " ) ]
{
android_logger ::init_once (
android_logger ::Config ::default ( )
. with_min_level ( log ::Level ::Debug ) // limit log level
. with_tag ( " ffi " ) , // logs will show under mytag tag
) ;
2022-09-15 20:40:29 +08:00
#[ cfg(feature = " mediacodec " ) ]
scrap ::mediacodec ::check_mediacodec ( ) ;
2022-09-29 13:07:20 +08:00
crate ::common ::test_rendezvous_server ( ) ;
crate ::common ::test_nat_type ( ) ;
crate ::common ::check_software_update ( ) ;
2022-05-12 17:35:25 +08:00
}
#[ cfg(target_os = " ios " ) ]
{
use hbb_common ::env_logger ::* ;
init_from_env ( Env ::default ( ) . filter_or ( DEFAULT_FILTER_ENV , " debug " ) ) ;
}
}
2022-05-31 22:09:36 +08:00
pub enum EventToUI {
Event ( String ) ,
Rgba ( ZeroCopyBuffer < Vec < u8 > > ) ,
2022-05-17 19:59:37 +08:00
}
2022-08-03 22:03:31 +08:00
pub fn start_global_event_stream ( s : StreamSink < String > , app_type : String ) -> ResultType < ( ) > {
2022-08-08 17:53:51 +08:00
if let Some ( _ ) = flutter ::GLOBAL_EVENT_STREAM
. write ( )
. unwrap ( )
. insert ( app_type . clone ( ) , s )
{
log ::warn! (
" Global event stream of type {} is started before, but now removed " ,
app_type
) ;
2022-08-03 22:03:31 +08:00
}
2022-05-19 23:45:44 +08:00
Ok ( ( ) )
}
2022-08-03 22:03:31 +08:00
pub fn stop_global_event_stream ( app_type : String ) {
2022-08-08 17:53:51 +08:00
let _ = flutter ::GLOBAL_EVENT_STREAM
. write ( )
. unwrap ( )
. remove ( & app_type ) ;
2022-08-03 22:03:31 +08:00
}
2022-09-06 00:39:11 +08:00
pub fn host_stop_system_key_propagate ( _stopped : bool ) {
2022-06-27 09:25:20 +08:00
#[ cfg(windows) ]
2022-09-06 00:39:11 +08:00
crate ::platform ::windows ::stop_system_key_propagate ( _stopped ) ;
2022-06-27 09:25:20 +08:00
}
2022-08-30 21:15:35 +08:00
// FIXME: -> ResultType<()> cannot be parsed by frb_codegen
// thread 'main' panicked at 'Failed to parse function output type `ResultType<()>`', $HOME\.cargo\git\checkouts\flutter_rust_bridge-ddba876d3ebb2a1e\e5adce5\frb_codegen\src\parser\mod.rs:151:25
2022-09-05 10:27:33 +08:00
pub fn session_add_sync (
id : String ,
is_file_transfer : bool ,
is_port_forward : bool ,
) -> SyncReturn < String > {
2022-08-31 20:46:30 +08:00
if let Err ( e ) = session_add ( & id , is_file_transfer , is_port_forward ) {
2022-08-30 21:15:35 +08:00
SyncReturn ( format! ( " Failed to add session with id {} , {} " , & id , e ) )
} else {
SyncReturn ( " " . to_owned ( ) )
}
}
pub fn session_start ( events2ui : StreamSink < EventToUI > , id : String ) -> ResultType < ( ) > {
2022-08-31 20:46:30 +08:00
session_start_ ( & id , events2ui )
2022-05-31 17:36:36 +08:00
}
2022-08-16 15:22:57 +08:00
pub fn session_get_remember ( id : String ) -> Option < bool > {
2022-05-31 17:36:36 +08:00
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
Some ( session . get_remember ( ) )
} else {
None
}
}
2022-08-16 15:22:57 +08:00
pub fn session_get_toggle_option ( id : String , arg : String ) -> Option < bool > {
2022-05-31 17:36:36 +08:00
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
2022-08-31 20:46:30 +08:00
Some ( session . get_toggle_option ( arg ) )
2022-05-31 17:36:36 +08:00
} else {
None
}
}
2022-08-16 15:22:57 +08:00
pub fn session_get_toggle_option_sync ( id : String , arg : String ) -> SyncReturn < bool > {
let res = session_get_toggle_option ( id , arg ) = = Some ( true ) ;
2022-06-01 15:09:48 +08:00
SyncReturn ( res )
2022-05-31 22:09:36 +08:00
}
2022-08-16 15:22:57 +08:00
pub fn session_get_option ( id : String , arg : String ) -> Option < String > {
2022-05-31 17:36:36 +08:00
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
2022-08-31 20:46:30 +08:00
Some ( session . get_option ( arg ) )
2022-05-31 17:36:36 +08:00
} else {
None
}
}
pub fn session_login ( id : String , password : String , remember : bool ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
2022-08-31 20:46:30 +08:00
session . login ( password , remember ) ;
2022-05-31 17:36:36 +08:00
}
}
pub fn session_close ( id : String ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . close ( ) ;
}
2022-06-28 22:05:49 +08:00
let _ = SESSIONS . write ( ) . unwrap ( ) . remove ( & id ) ;
2022-05-31 17:36:36 +08:00
}
pub fn session_refresh ( id : String ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
2022-08-31 20:46:30 +08:00
session . refresh_video ( ) ;
2022-05-31 17:36:36 +08:00
}
}
2022-09-15 17:31:28 +08:00
pub fn session_record_screen ( id : String , start : bool , width : usize , height : usize ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . record_screen ( start , width as _ , height as _ ) ;
}
}
2022-05-31 17:36:36 +08:00
pub fn session_reconnect ( id : String ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . reconnect ( ) ;
}
}
pub fn session_toggle_option ( id : String , value : String ) {
2022-08-31 20:46:30 +08:00
if let Some ( session ) = SESSIONS . write ( ) . unwrap ( ) . get_mut ( & id ) {
session . toggle_option ( value ) ;
2022-05-31 17:36:36 +08:00
}
}
2022-08-31 18:41:55 +08:00
pub fn session_get_image_quality ( id : String ) -> Option < String > {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
Some ( session . get_image_quality ( ) )
} else {
None
}
}
2022-05-31 17:36:36 +08:00
pub fn session_set_image_quality ( id : String , value : String ) {
2022-09-01 17:36:37 +08:00
if let Some ( session ) = SESSIONS . write ( ) . unwrap ( ) . get_mut ( & id ) {
session . save_image_quality ( value ) ;
2022-08-31 18:41:55 +08:00
}
}
pub fn session_get_custom_image_quality ( id : String ) -> Option < Vec < i32 > > {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
Some ( session . get_custom_image_quality ( ) )
} else {
None
}
}
pub fn session_set_custom_image_quality ( id : String , value : i32 ) {
2022-09-01 21:18:29 +08:00
if let Some ( session ) = SESSIONS . write ( ) . unwrap ( ) . get_mut ( & id ) {
session . save_custom_image_quality ( value ) ;
2022-05-31 17:36:36 +08:00
}
}
pub fn session_lock_screen ( id : String ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . lock_screen ( ) ;
}
}
pub fn session_ctrl_alt_del ( id : String ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . ctrl_alt_del ( ) ;
}
}
pub fn session_switch_display ( id : String , value : i32 ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . switch_display ( value ) ;
}
}
2022-09-02 19:49:36 +08:00
pub fn session_handle_flutter_key_event (
id : String ,
name : String ,
keycode : i32 ,
scancode : i32 ,
down_or_up : bool ,
) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . handle_flutter_key_event ( & name , keycode , scancode , down_or_up ) ;
}
}
2022-08-27 09:29:46 +08:00
2022-09-05 18:19:05 +08:00
pub fn session_enter_or_leave ( id : String , enter : bool ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
if enter {
session . enter ( ) ;
} else {
session . leave ( ) ;
}
}
}
2022-05-31 17:36:36 +08:00
pub fn session_input_key (
id : String ,
name : String ,
down : bool ,
press : bool ,
alt : bool ,
ctrl : bool ,
shift : bool ,
command : bool ,
) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . input_key ( & name , down , press , alt , ctrl , shift , command ) ;
}
}
pub fn session_input_string ( id : String , value : String ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . input_string ( & value ) ;
}
}
// chat_client_mode
pub fn session_send_chat ( id : String , text : String ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . send_chat ( text ) ;
}
2022-05-31 14:44:06 +08:00
}
2022-05-31 17:36:36 +08:00
pub fn session_peer_option ( id : String , name : String , value : String ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . set_option ( name , value ) ;
}
}
2022-07-01 11:26:32 +08:00
pub fn session_get_peer_option ( id : String , name : String ) -> String {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
2022-08-31 20:46:30 +08:00
return session . get_option ( name ) ;
2022-07-01 11:26:32 +08:00
}
" " . to_string ( )
}
2022-09-05 22:18:29 +08:00
pub fn session_get_keyboard_name ( id : String ) -> String {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
return session . get_keyboard_mode ( ) ;
}
" legacy " . to_string ( )
}
pub fn session_set_keyboard_mode ( id : String , keyboard_mode : String ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . save_keyboard_mode ( keyboard_mode ) ;
}
}
2022-05-31 17:36:36 +08:00
pub fn session_input_os_password ( id : String , value : String ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . input_os_password ( value , true ) ;
}
}
// File Action
pub fn session_read_remote_dir ( id : String , path : String , include_hidden : bool ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . read_remote_dir ( path , include_hidden ) ;
}
}
pub fn session_send_files (
id : String ,
act_id : i32 ,
path : String ,
to : String ,
file_num : i32 ,
include_hidden : bool ,
is_remote : bool ,
) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . send_files ( act_id , path , to , file_num , include_hidden , is_remote ) ;
}
}
pub fn session_set_confirm_override_file (
id : String ,
act_id : i32 ,
file_num : i32 ,
need_override : bool ,
remember : bool ,
is_upload : bool ,
) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . set_confirm_override_file ( act_id , file_num , need_override , remember , is_upload ) ;
}
}
pub fn session_remove_file ( id : String , act_id : i32 , path : String , file_num : i32 , is_remote : bool ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . remove_file ( act_id , path , file_num , is_remote ) ;
}
}
2022-07-01 11:26:32 +08:00
pub fn session_read_dir_recursive (
id : String ,
act_id : i32 ,
path : String ,
is_remote : bool ,
show_hidden : bool ,
) {
2022-05-31 17:36:36 +08:00
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
2022-07-01 11:26:32 +08:00
session . remove_dir_all ( act_id , path , is_remote , show_hidden ) ;
2022-05-31 17:36:36 +08:00
}
}
pub fn session_remove_all_empty_dirs ( id : String , act_id : i32 , path : String , is_remote : bool ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . remove_dir ( act_id , path , is_remote ) ;
}
}
pub fn session_cancel_job ( id : String , act_id : i32 ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . cancel_job ( act_id ) ;
}
}
pub fn session_create_dir ( id : String , act_id : i32 , path : String , is_remote : bool ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . create_dir ( act_id , path , is_remote ) ;
}
2022-05-31 14:44:06 +08:00
}
2022-06-21 17:58:27 +08:00
pub fn session_read_local_dir_sync ( id : String , path : String , show_hidden : bool ) -> String {
2022-09-05 10:27:33 +08:00
if let Ok ( fd ) = fs ::read_dir ( & fs ::get_path ( & path ) , show_hidden ) {
return make_fd_to_json ( fd . id , path , & fd . entries ) ;
2022-06-21 17:58:27 +08:00
}
" " . to_string ( )
}
2022-07-11 16:07:49 +08:00
pub fn session_get_platform ( id : String , is_remote : bool ) -> String {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
return session . get_platform ( is_remote ) ;
}
" " . to_string ( )
}
pub fn session_load_last_transfer_jobs ( id : String ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
2022-09-06 19:08:45 +08:00
return session . load_last_jobs ( ) ;
2022-07-11 18:23:58 +08:00
} else {
// a tip for flutter dev
eprintln! (
" cannot load last transfer job from non-existed session. Please ensure session \
is connected before calling load last transfer jobs . "
) ;
}
}
pub fn session_add_job (
id : String ,
act_id : i32 ,
path : String ,
to : String ,
file_num : i32 ,
include_hidden : bool ,
is_remote : bool ,
) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . add_job ( act_id , path , to , file_num , include_hidden , is_remote ) ;
}
}
pub fn session_resume_job ( id : String , act_id : i32 , is_remote : bool ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . resume_job ( act_id , is_remote ) ;
2022-07-11 16:07:49 +08:00
}
}
2022-07-14 12:32:01 +08:00
pub fn main_get_sound_inputs ( ) -> Vec < String > {
2022-09-14 17:37:52 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
return get_sound_inputs ( ) ;
#[ cfg(any(target_os = " android " , target_os = " linux " )) ]
vec! [ String ::from ( " " ) ]
2022-07-14 12:32:01 +08:00
}
2022-07-15 17:00:37 +08:00
pub fn main_change_id ( new_id : String ) {
change_id ( new_id )
}
pub fn main_get_async_status ( ) -> String {
get_async_job_status ( )
}
2022-08-08 17:53:51 +08:00
pub fn main_get_option ( key : String ) -> String {
get_option ( key )
}
pub fn main_set_option ( key : String , value : String ) {
if key . eq ( " custom-rendezvous-server " ) {
set_option ( key , value ) ;
#[ cfg(target_os = " android " ) ]
crate ::rendezvous_mediator ::RendezvousMediator ::restart ( ) ;
2022-08-08 22:27:27 +08:00
#[ cfg(any(target_os = " android " , target_os = " ios " , feature = " cli " )) ]
2022-08-08 17:53:51 +08:00
crate ::common ::test_rendezvous_server ( ) ;
} else {
set_option ( key , value ) ;
}
}
2022-07-18 18:20:00 +08:00
pub fn main_get_options ( ) -> String {
get_options ( )
}
pub fn main_set_options ( json : String ) {
let map : HashMap < String , String > = serde_json ::from_str ( & json ) . unwrap_or ( HashMap ::new ( ) ) ;
if ! map . is_empty ( ) {
set_options ( map )
}
}
pub fn main_test_if_valid_server ( server : String ) -> String {
test_if_valid_server ( server )
}
pub fn main_set_socks ( proxy : String , username : String , password : String ) {
set_socks ( proxy , username , password )
}
pub fn main_get_socks ( ) -> Vec < String > {
get_socks ( )
}
pub fn main_get_app_name ( ) -> String {
get_app_name ( )
}
2022-09-25 21:45:37 +08:00
pub fn main_get_app_name_sync ( ) -> SyncReturn < String > {
SyncReturn ( get_app_name ( ) )
}
2022-07-18 18:20:00 +08:00
pub fn main_get_license ( ) -> String {
get_license ( )
}
pub fn main_get_version ( ) -> String {
get_version ( )
}
2022-07-22 23:12:31 +08:00
pub fn main_get_fav ( ) -> Vec < String > {
get_fav ( )
}
pub fn main_store_fav ( favs : Vec < String > ) {
store_fav ( favs )
}
2022-08-08 17:53:51 +08:00
pub fn main_get_peer ( id : String ) -> String {
2022-07-22 23:12:31 +08:00
let conf = get_peer ( id ) ;
serde_json ::to_string ( & conf ) . unwrap_or ( " " . to_string ( ) )
}
pub fn main_get_lan_peers ( ) -> String {
2022-08-24 23:22:50 +08:00
serde_json ::to_string ( & get_lan_peers ( ) ) . unwrap_or_default ( )
2022-07-22 23:12:31 +08:00
}
2022-07-25 16:23:45 +08:00
pub fn main_get_connect_status ( ) -> String {
let status = get_connect_status ( ) ;
// (status_num, key_confirmed, mouse_time, id)
let mut m = serde_json ::Map ::new ( ) ;
m . insert ( " status_num " . to_string ( ) , json! ( status . 0 ) ) ;
m . insert ( " key_confirmed " . to_string ( ) , json! ( status . 1 ) ) ;
m . insert ( " mouse_time " . to_string ( ) , json! ( status . 2 ) ) ;
m . insert ( " id " . to_string ( ) , json! ( status . 3 ) ) ;
serde_json ::to_string ( & m ) . unwrap_or ( " " . to_string ( ) )
}
pub fn main_check_connect_status ( ) {
2022-08-03 21:51:35 +08:00
#[ cfg(not(any(target_os = " android " , target_os = " ios " ))) ]
2022-08-30 16:50:25 +08:00
check_mouse_time ( ) ; // avoid multi calls
2022-07-25 16:23:45 +08:00
}
pub fn main_is_using_public_server ( ) -> bool {
using_public_server ( )
}
2022-08-02 13:10:09 +08:00
pub fn main_discover ( ) {
discover ( ) ;
}
2022-07-25 16:23:45 +08:00
pub fn main_has_rendezvous_service ( ) -> bool {
has_rendezvous_service ( )
}
pub fn main_get_api_server ( ) -> String {
get_api_server ( )
}
pub fn main_post_request ( url : String , body : String , header : String ) {
post_request ( url , body , header )
}
pub fn main_get_local_option ( key : String ) -> String {
get_local_option ( key )
}
pub fn main_set_local_option ( key : String , value : String ) {
set_local_option ( key , value )
}
2022-07-27 14:29:47 +08:00
pub fn main_get_my_id ( ) -> String {
get_id ( )
}
pub fn main_get_uuid ( ) -> String {
get_uuid ( )
}
2022-07-29 12:03:24 +08:00
pub fn main_get_peer_option ( id : String , key : String ) -> String {
get_peer_option ( id , key )
}
2022-09-22 15:59:51 +08:00
pub fn main_get_peer_option_sync ( id : String , key : String ) -> SyncReturn < String > {
SyncReturn ( get_peer_option ( id , key ) )
}
2022-07-29 12:03:24 +08:00
pub fn main_set_peer_option ( id : String , key : String , value : String ) {
set_peer_option ( id , key , value )
}
2022-09-22 15:59:51 +08:00
pub fn main_set_peer_option_sync ( id : String , key : String , value : String ) -> SyncReturn < bool > {
set_peer_option ( id , key , value ) ;
SyncReturn ( true )
}
2022-07-29 16:47:24 +08:00
pub fn main_forget_password ( id : String ) {
forget_password ( id )
}
2022-09-25 21:03:19 +08:00
pub fn main_peer_has_password ( id : String ) -> bool {
peer_has_password ( id )
}
2022-08-08 17:53:51 +08:00
pub fn main_get_recent_peers ( ) -> String {
if ! config ::APP_DIR . read ( ) . unwrap ( ) . is_empty ( ) {
2022-09-21 21:20:19 +08:00
let peers : Vec < HashMap < & str , String > > = PeerConfig ::peers ( )
2022-08-08 17:53:51 +08:00
. drain ( .. )
2022-09-21 21:20:19 +08:00
. map ( | ( id , _ , p ) | {
HashMap ::< & str , String > ::from_iter ( [
( " id " , id ) ,
( " username " , p . info . username . clone ( ) ) ,
( " hostname " , p . info . hostname . clone ( ) ) ,
( " platform " , p . info . platform . clone ( ) ) ,
(
" alias " ,
p . options . get ( " alias " ) . unwrap_or ( & " " . to_owned ( ) ) . to_owned ( ) ,
) ,
] )
} )
2022-08-08 17:53:51 +08:00
. collect ( ) ;
serde_json ::ser ::to_string ( & peers ) . unwrap_or ( " " . to_owned ( ) )
} else {
String ::new ( )
}
}
2022-08-02 13:10:09 +08:00
pub fn main_load_recent_peers ( ) {
if ! config ::APP_DIR . read ( ) . unwrap ( ) . is_empty ( ) {
2022-09-21 21:20:19 +08:00
let peers : Vec < HashMap < & str , String > > = PeerConfig ::peers ( )
2022-08-02 13:10:09 +08:00
. drain ( .. )
2022-09-21 21:20:19 +08:00
. map ( | ( id , _ , p ) | {
HashMap ::< & str , String > ::from_iter ( [
( " id " , id ) ,
( " username " , p . info . username . clone ( ) ) ,
( " hostname " , p . info . hostname . clone ( ) ) ,
( " platform " , p . info . platform . clone ( ) ) ,
(
" alias " ,
p . options . get ( " alias " ) . unwrap_or ( & " " . to_owned ( ) ) . to_owned ( ) ,
) ,
] )
} )
2022-08-02 13:10:09 +08:00
. collect ( ) ;
2022-08-08 17:53:51 +08:00
if let Some ( s ) = flutter ::GLOBAL_EVENT_STREAM
. read ( )
. unwrap ( )
. get ( flutter ::APP_TYPE_MAIN )
{
2022-08-02 13:10:09 +08:00
let data = HashMap ::from ( [
( " name " , " load_recent_peers " . to_owned ( ) ) ,
(
" peers " ,
serde_json ::ser ::to_string ( & peers ) . unwrap_or ( " " . to_owned ( ) ) ,
) ,
] ) ;
s . add ( serde_json ::ser ::to_string ( & data ) . unwrap_or ( " " . to_owned ( ) ) ) ;
} ;
}
}
pub fn main_load_fav_peers ( ) {
if ! config ::APP_DIR . read ( ) . unwrap ( ) . is_empty ( ) {
let favs = get_fav ( ) ;
2022-09-21 21:20:19 +08:00
let peers : Vec < HashMap < & str , String > > = PeerConfig ::peers ( )
2022-08-02 13:10:09 +08:00
. into_iter ( )
2022-09-21 21:20:19 +08:00
. filter_map ( | ( id , _ , p ) | {
2022-08-02 13:10:09 +08:00
if favs . contains ( & id ) {
2022-09-21 21:20:19 +08:00
Some ( HashMap ::< & str , String > ::from_iter ( [
( " id " , id ) ,
( " username " , p . info . username . clone ( ) ) ,
( " hostname " , p . info . hostname . clone ( ) ) ,
( " platform " , p . info . platform . clone ( ) ) ,
(
" alias " ,
p . options . get ( " alias " ) . unwrap_or ( & " " . to_owned ( ) ) . to_owned ( ) ,
) ,
] ) )
2022-08-02 13:10:09 +08:00
} else {
None
}
} )
. collect ( ) ;
2022-08-08 17:53:51 +08:00
if let Some ( s ) = flutter ::GLOBAL_EVENT_STREAM
. read ( )
. unwrap ( )
. get ( flutter ::APP_TYPE_MAIN )
{
2022-08-02 13:10:09 +08:00
let data = HashMap ::from ( [
( " name " , " load_fav_peers " . to_owned ( ) ) ,
(
" peers " ,
serde_json ::ser ::to_string ( & peers ) . unwrap_or ( " " . to_owned ( ) ) ,
) ,
] ) ;
s . add ( serde_json ::ser ::to_string ( & data ) . unwrap_or ( " " . to_owned ( ) ) ) ;
} ;
}
}
pub fn main_load_lan_peers ( ) {
2022-08-08 17:53:51 +08:00
if let Some ( s ) = flutter ::GLOBAL_EVENT_STREAM
. read ( )
. unwrap ( )
. get ( flutter ::APP_TYPE_MAIN )
{
2022-08-02 13:10:09 +08:00
let data = HashMap ::from ( [
( " name " , " load_lan_peers " . to_owned ( ) ) ,
2022-08-26 11:35:28 +08:00
(
" peers " ,
serde_json ::to_string ( & get_lan_peers ( ) ) . unwrap_or_default ( ) ,
) ,
2022-08-02 13:10:09 +08:00
] ) ;
s . add ( serde_json ::ser ::to_string ( & data ) . unwrap_or ( " " . to_owned ( ) ) ) ;
} ;
}
2022-09-08 08:52:56 +08:00
fn main_broadcast_message ( data : & HashMap < & str , & str > ) {
2022-09-07 18:57:49 +08:00
let apps = vec! [
flutter ::APP_TYPE_DESKTOP_REMOTE ,
flutter ::APP_TYPE_DESKTOP_FILE_TRANSFER ,
flutter ::APP_TYPE_DESKTOP_PORT_FORWARD ,
] ;
for app in apps {
if let Some ( s ) = flutter ::GLOBAL_EVENT_STREAM . read ( ) . unwrap ( ) . get ( app ) {
2022-09-08 08:52:56 +08:00
s . add ( serde_json ::ser ::to_string ( data ) . unwrap_or ( " " . to_owned ( ) ) ) ;
2022-09-07 18:57:49 +08:00
} ;
}
2022-09-08 08:52:56 +08:00
}
2022-09-21 23:32:59 +08:00
pub fn main_change_theme ( dark : String ) {
2022-09-22 15:59:51 +08:00
main_broadcast_message ( & HashMap ::from ( [ ( " name " , " theme " ) , ( " dark " , & dark ) ] ) ) ;
2022-09-07 18:57:49 +08:00
send_to_cm ( & crate ::ipc ::Data ::Theme ( dark ) ) ;
}
2022-09-08 08:52:56 +08:00
pub fn main_change_language ( lang : String ) {
main_broadcast_message ( & HashMap ::from ( [ ( " name " , " language " ) , ( " lang " , & lang ) ] ) ) ;
send_to_cm ( & crate ::ipc ::Data ::Language ( lang ) ) ;
}
2022-09-15 17:31:28 +08:00
pub fn main_default_video_save_directory ( ) -> String {
default_video_save_directory ( )
}
2022-08-30 21:15:35 +08:00
pub fn session_add_port_forward (
id : String ,
local_port : i32 ,
remote_host : String ,
remote_port : i32 ,
) {
2022-08-29 13:08:42 +08:00
if let Some ( session ) = SESSIONS . write ( ) . unwrap ( ) . get_mut ( & id ) {
session . add_port_forward ( local_port , remote_host , remote_port ) ;
2022-08-26 11:35:28 +08:00
}
}
2022-08-29 13:08:42 +08:00
pub fn session_remove_port_forward ( id : String , local_port : i32 ) {
if let Some ( session ) = SESSIONS . write ( ) . unwrap ( ) . get_mut ( & id ) {
session . remove_port_forward ( local_port ) ;
}
2022-08-26 11:35:28 +08:00
}
2022-09-08 17:22:24 +08:00
pub fn session_new_rdp ( id : String ) {
if let Some ( session ) = SESSIONS . write ( ) . unwrap ( ) . get_mut ( & id ) {
session . new_rdp ( ) ;
}
}
2022-08-08 17:53:51 +08:00
pub fn main_get_last_remote_id ( ) -> String {
LocalConfig ::get_remote_id ( )
}
2022-08-08 22:27:27 +08:00
pub fn main_get_software_update_url ( ) -> String {
crate ::common ::SOFTWARE_UPDATE_URL . lock ( ) . unwrap ( ) . clone ( )
}
pub fn main_get_home_dir ( ) -> String {
fs ::get_home_as_string ( )
}
pub fn main_get_langs ( ) -> String {
2022-08-13 12:43:35 +08:00
get_langs ( )
2022-08-08 22:27:27 +08:00
}
pub fn main_get_temporary_password ( ) -> String {
ui_interface ::temporary_password ( )
}
pub fn main_get_permanent_password ( ) -> String {
ui_interface ::permanent_password ( )
}
pub fn main_get_online_statue ( ) -> i64 {
ONLINE . lock ( ) . unwrap ( ) . values ( ) . max ( ) . unwrap_or ( & 0 ) . clone ( )
}
2022-09-05 19:41:09 +08:00
pub fn cm_get_clients_state ( ) -> String {
crate ::ui_cm_interface ::get_clients_state ( )
2022-08-08 22:27:27 +08:00
}
2022-09-05 19:41:09 +08:00
pub fn cm_check_clients_length ( length : usize ) -> Option < String > {
if length ! = crate ::ui_cm_interface ::get_clients_length ( ) {
Some ( crate ::ui_cm_interface ::get_clients_state ( ) )
2022-08-08 22:27:27 +08:00
} else {
None
}
}
2022-10-08 20:15:02 +08:00
pub fn cm_get_clients_length ( ) -> usize {
crate ::ui_cm_interface ::get_clients_length ( )
}
2022-08-08 22:27:27 +08:00
pub fn main_init ( app_dir : String ) {
initialize ( & app_dir ) ;
}
pub fn main_device_id ( id : String ) {
* crate ::common ::DEVICE_ID . lock ( ) . unwrap ( ) = id ;
}
pub fn main_device_name ( name : String ) {
* crate ::common ::DEVICE_NAME . lock ( ) . unwrap ( ) = name ;
}
pub fn main_remove_peer ( id : String ) {
PeerConfig ::remove ( & id ) ;
}
2022-09-16 19:43:28 +08:00
pub fn main_has_hwcodec ( ) -> SyncReturn < bool > {
SyncReturn ( has_hwcodec ( ) )
2022-08-15 11:08:42 +08:00
}
2022-09-27 13:30:49 +08:00
pub fn main_is_root ( ) -> bool {
is_root ( )
}
pub fn main_is_release ( ) -> bool {
is_release ( )
}
2022-10-11 19:52:03 +08:00
pub fn main_start_dbus_server ( ) {
#[ cfg(target_os = " linux " ) ]
{
use crate ::dbus ::start_dbus_server ;
// spawn new thread to start dbus server
std ::thread ::spawn ( | | {
let _ = start_dbus_server ( ) ;
} ) ;
}
}
2022-08-08 22:27:27 +08:00
pub fn session_send_mouse ( id : String , msg : String ) {
if let Ok ( m ) = serde_json ::from_str ::< HashMap < String , String > > ( & msg ) {
let alt = m . get ( " alt " ) . is_some ( ) ;
let ctrl = m . get ( " ctrl " ) . is_some ( ) ;
let shift = m . get ( " shift " ) . is_some ( ) ;
let command = m . get ( " command " ) . is_some ( ) ;
let x = m
. get ( " x " )
. map ( | x | x . parse ::< i32 > ( ) . unwrap_or ( 0 ) )
. unwrap_or ( 0 ) ;
let y = m
. get ( " y " )
. map ( | x | x . parse ::< i32 > ( ) . unwrap_or ( 0 ) )
. unwrap_or ( 0 ) ;
let mut mask = 0 ;
if let Some ( _type ) = m . get ( " type " ) {
mask = match _type . as_str ( ) {
" down " = > 1 ,
" up " = > 2 ,
" wheel " = > 3 ,
_ = > 0 ,
} ;
}
if let Some ( buttons ) = m . get ( " buttons " ) {
mask | = match buttons . as_str ( ) {
" left " = > 1 ,
" right " = > 2 ,
" wheel " = > 4 ,
_ = > 0 ,
} < < 3 ;
}
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . send_mouse ( mask , x , y , alt , ctrl , shift , command ) ;
}
}
}
pub fn session_restart_remote_device ( id : String ) {
2022-08-15 19:31:58 +08:00
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . restart_remote_device ( ) ;
}
2022-08-08 22:27:27 +08:00
}
2022-09-08 15:35:19 +08:00
pub fn session_get_audit_server_sync ( id : String ) -> SyncReturn < String > {
let res = if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . get_audit_server ( )
} else {
" " . to_owned ( )
} ;
SyncReturn ( res )
}
pub fn session_send_note ( id : String , note : String ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . send_note ( note )
}
}
2022-09-16 19:43:28 +08:00
pub fn session_supported_hwcodec ( id : String ) -> String {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
let ( h264 , h265 ) = session . supported_hwcodec ( ) ;
let msg = HashMap ::from ( [ ( " h264 " , h264 ) , ( " h265 " , h265 ) ] ) ;
serde_json ::ser ::to_string ( & msg ) . unwrap_or ( " " . to_owned ( ) )
} else {
String ::new ( )
}
}
pub fn session_change_prefer_codec ( id : String ) {
if let Some ( session ) = SESSIONS . read ( ) . unwrap ( ) . get ( & id ) {
session . change_prefer_codec ( ) ;
}
}
2022-08-08 22:27:27 +08:00
pub fn main_set_home_dir ( home : String ) {
* config ::APP_HOME_DIR . write ( ) . unwrap ( ) = home ;
}
pub fn main_stop_service ( ) {
#[ cfg(target_os = " android " ) ]
{
2022-09-05 20:05:23 +08:00
config ::Config ::set_option ( " stop-service " . into ( ) , " Y " . into ( ) ) ;
2022-08-08 22:27:27 +08:00
crate ::rendezvous_mediator ::RendezvousMediator ::restart ( ) ;
}
}
pub fn main_start_service ( ) {
#[ cfg(target_os = " android " ) ]
{
2022-09-05 20:05:23 +08:00
config ::Config ::set_option ( " stop-service " . into ( ) , " " . into ( ) ) ;
2022-08-08 22:27:27 +08:00
crate ::rendezvous_mediator ::RendezvousMediator ::restart ( ) ;
}
}
pub fn main_update_temporary_password ( ) {
update_temporary_password ( ) ;
}
pub fn main_set_permanent_password ( password : String ) {
set_permanent_password ( password ) ;
}
2022-08-19 15:44:19 +08:00
pub fn main_check_super_user_permission ( ) -> bool {
check_super_user_permission ( )
}
2022-08-30 16:50:25 +08:00
pub fn main_check_mouse_time ( ) {
check_mouse_time ( ) ;
}
pub fn main_get_mouse_time ( ) -> f64 {
get_mouse_time ( )
}
2022-09-06 17:08:59 +08:00
pub fn main_wol ( id : String ) {
crate ::lan ::send_wol ( id )
}
2022-08-17 17:23:55 +08:00
pub fn cm_send_chat ( conn_id : i32 , msg : String ) {
2022-09-05 19:41:09 +08:00
crate ::ui_cm_interface ::send_chat ( conn_id , msg ) ;
2022-08-08 22:27:27 +08:00
}
2022-08-17 17:23:55 +08:00
pub fn cm_login_res ( conn_id : i32 , res : bool ) {
2022-09-05 19:41:09 +08:00
if res {
crate ::ui_cm_interface ::authorize ( conn_id ) ;
} else {
crate ::ui_cm_interface ::close ( conn_id ) ;
}
2022-08-08 22:27:27 +08:00
}
2022-08-17 17:23:55 +08:00
pub fn cm_close_connection ( conn_id : i32 ) {
2022-09-05 19:41:09 +08:00
crate ::ui_cm_interface ::close ( conn_id ) ;
2022-08-08 22:27:27 +08:00
}
2022-10-08 20:15:02 +08:00
pub fn cm_remove_disconnected_connection ( conn_id : i32 ) {
crate ::ui_cm_interface ::remove ( conn_id ) ;
}
2022-08-17 17:23:55 +08:00
pub fn cm_check_click_time ( conn_id : i32 ) {
2022-09-05 19:41:09 +08:00
crate ::ui_cm_interface ::check_click_time ( conn_id )
2022-08-17 17:23:55 +08:00
}
pub fn cm_get_click_time ( ) -> f64 {
2022-09-05 19:41:09 +08:00
crate ::ui_cm_interface ::get_click_time ( ) as _
2022-08-17 17:23:55 +08:00
}
pub fn cm_switch_permission ( conn_id : i32 , name : String , enabled : bool ) {
2022-09-05 19:41:09 +08:00
crate ::ui_cm_interface ::switch_permission ( conn_id , name , enabled )
2022-08-17 17:23:55 +08:00
}
pub fn main_get_icon ( ) -> String {
#[ cfg(not(any(target_os = " android " , target_os = " ios " , feature = " cli " ))) ]
return ui_interface ::get_icon ( ) ;
#[ cfg(any(target_os = " android " , target_os = " ios " , feature = " cli " )) ]
return String ::new ( ) ;
}
2022-08-08 17:53:51 +08:00
#[ no_mangle ]
unsafe extern " C " fn translate ( name : * const c_char , locale : * const c_char ) -> * const c_char {
let name = CStr ::from_ptr ( name ) ;
let locale = CStr ::from_ptr ( locale ) ;
let res = if let ( Ok ( name ) , Ok ( locale ) ) = ( name . to_str ( ) , locale . to_str ( ) ) {
crate ::client ::translate_locale ( name . to_owned ( ) , locale )
} else {
String ::new ( )
} ;
CString ::from_vec_unchecked ( res . into_bytes ( ) ) . into_raw ( )
}
2022-07-27 22:56:28 +08:00
fn handle_query_onlines ( onlines : Vec < String > , offlines : Vec < String > ) {
2022-08-08 17:53:51 +08:00
if let Some ( s ) = flutter ::GLOBAL_EVENT_STREAM
. read ( )
. unwrap ( )
. get ( flutter ::APP_TYPE_MAIN )
{
2022-07-27 22:56:28 +08:00
let data = HashMap ::from ( [
( " name " , " callback_query_onlines " . to_owned ( ) ) ,
( " onlines " , onlines . join ( " , " ) ) ,
( " offlines " , offlines . join ( " , " ) ) ,
] ) ;
s . add ( serde_json ::ser ::to_string ( & data ) . unwrap_or ( " " . to_owned ( ) ) ) ;
} ;
}
pub fn query_onlines ( ids : Vec < String > ) {
crate ::rendezvous_mediator ::query_online_states ( ids , handle_query_onlines )
}
2022-09-22 15:59:51 +08:00
pub fn main_is_installed ( ) -> SyncReturn < bool > {
SyncReturn ( is_installed ( ) )
}
pub fn main_is_installed_lower_version ( ) -> SyncReturn < bool > {
SyncReturn ( is_installed_lower_version ( ) )
}
pub fn main_is_installed_daemon ( prompt : bool ) -> SyncReturn < bool > {
SyncReturn ( is_installed_daemon ( prompt ) )
}
pub fn main_is_process_trusted ( prompt : bool ) -> SyncReturn < bool > {
SyncReturn ( is_process_trusted ( prompt ) )
}
pub fn main_is_can_screen_recording ( prompt : bool ) -> SyncReturn < bool > {
SyncReturn ( is_can_screen_recording ( prompt ) )
}
pub fn main_is_share_rdp ( ) -> SyncReturn < bool > {
SyncReturn ( is_share_rdp ( ) )
}
pub fn main_is_rdp_service_open ( ) -> SyncReturn < bool > {
SyncReturn ( is_rdp_service_open ( ) )
}
2022-09-25 21:45:37 +08:00
pub fn main_goto_install ( ) -> SyncReturn < bool > {
goto_install ( ) ;
SyncReturn ( true )
}
pub fn main_get_new_version ( ) -> SyncReturn < String > {
SyncReturn ( get_new_version ( ) )
}
pub fn main_update_me ( ) -> SyncReturn < bool > {
update_me ( " " . to_owned ( ) ) ;
SyncReturn ( true )
}
2022-10-09 20:32:28 +08:00
pub fn install_show_run_without_install ( ) -> SyncReturn < bool > {
SyncReturn ( show_run_without_install ( ) )
}
pub fn install_run_without_install ( ) {
run_without_install ( ) ;
}
pub fn install_install_me ( options : String , path : String ) {
install_me ( options , path , false , false ) ;
}
pub fn install_install_path ( ) -> SyncReturn < String > {
SyncReturn ( install_path ( ) )
}
2022-05-12 17:35:25 +08:00
#[ cfg(target_os = " android " ) ]
pub mod server_side {
use jni ::{
objects ::{ JClass , JString } ,
sys ::jstring ,
JNIEnv ,
} ;
2022-07-01 11:26:32 +08:00
use hbb_common ::{ config ::Config , log } ;
2022-05-12 17:35:25 +08:00
use crate ::start_server ;
#[ no_mangle ]
pub unsafe extern " system " fn Java_com_carriez_flutter_1hbb_MainService_startServer (
env : JNIEnv ,
_class : JClass ,
) {
log ::debug! ( " startServer from java " ) ;
std ::thread ::spawn ( move | | start_server ( true ) ) ;
}
#[ no_mangle ]
pub unsafe extern " system " fn Java_com_carriez_flutter_1hbb_MainService_translateLocale (
env : JNIEnv ,
_class : JClass ,
locale : JString ,
input : JString ,
) -> jstring {
let res = if let ( Ok ( input ) , Ok ( locale ) ) = ( env . get_string ( input ) , env . get_string ( locale ) ) {
let input : String = input . into ( ) ;
let locale : String = locale . into ( ) ;
crate ::client ::translate_locale ( input , & locale )
} else {
" " . into ( )
} ;
return env . new_string ( res ) . unwrap_or ( input ) . into_inner ( ) ;
}
#[ no_mangle ]
pub unsafe extern " system " fn Java_com_carriez_flutter_1hbb_MainService_refreshScreen (
_env : JNIEnv ,
_class : JClass ,
) {
crate ::server ::video_service ::refresh ( )
}
}