From 0c30d34cc2055a560b438a2263f9bf4d92560704 Mon Sep 17 00:00:00 2001 From: csf Date: Tue, 25 Oct 2022 10:16:11 +0900 Subject: [PATCH] add android screen record (incoming session) --- flutter/lib/mobile/pages/settings_page.dart | 57 +++++++++++++++++++++ src/server/video_service.rs | 6 +-- src/ui_cm_interface.rs | 2 +- src/ui_interface.rs | 11 ++++ 4 files changed, 72 insertions(+), 4 deletions(-) diff --git a/flutter/lib/mobile/pages/settings_page.dart b/flutter/lib/mobile/pages/settings_page.dart index c555314d0..7a82bcdd8 100644 --- a/flutter/lib/mobile/pages/settings_page.dart +++ b/flutter/lib/mobile/pages/settings_page.dart @@ -36,6 +36,8 @@ var _enableAbr = false; var _denyLANDiscovery = false; var _onlyWhiteList = false; var _enableDirectIPAccess = false; +var _enableRecordSession = false; +var _autoRecordIncomingSession = false; var _localIP = ""; var _directAccessPort = ""; @@ -78,6 +80,21 @@ class _SettingsState extends State with WidgetsBindingObserver { _enableDirectIPAccess = enableDirectIPAccess; } + final enableRecordSession = option2bool('enable-record-session', + await bind.mainGetOption(key: 'enable-record-session')); + if (enableRecordSession != _enableRecordSession) { + update = true; + _enableRecordSession = enableRecordSession; + } + + final autoRecordIncomingSession = option2bool( + 'allow-auto-record-incoming', + await bind.mainGetOption(key: 'allow-auto-record-incoming')); + if (autoRecordIncomingSession != _autoRecordIncomingSession) { + update = true; + _autoRecordIncomingSession = autoRecordIncomingSession; + } + final localIP = await bind.mainGetOption(key: 'local-ip-addr'); if (localIP != _localIP) { update = true; @@ -178,6 +195,19 @@ class _SettingsState extends State with WidgetsBindingObserver { }); }, ), + SettingsTile.switchTile( + title: Text(translate('Enable Recording Session')), + initialValue: _enableRecordSession, + onToggle: (v) async { + await bind.mainSetOption( + key: "enable-record-session", value: v ? "" : "N"); + final newValue = + await bind.mainGetOption(key: "enable-record-session") != "N"; + setState(() { + _enableRecordSession = newValue; + }); + }, + ), SettingsTile.switchTile( title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -299,6 +329,33 @@ class _SettingsState extends State with WidgetsBindingObserver { }, ) ]), + SettingsSection( + title: Text(translate("Recording")), + tiles: [ + SettingsTile.switchTile( + title: Text(translate('Automatically record incoming sessions')), + leading: Icon(Icons.videocam), + description: FutureBuilder( + builder: (ctx, data) => Offstage( + offstage: !data.hasData, + child: Text("${translate("Directory")}: ${data.data}")), + future: bind.mainDefaultVideoSaveDirectory()), + initialValue: _autoRecordIncomingSession, + onToggle: (v) async { + await bind.mainSetOption( + key: "allow-auto-record-incoming", + value: bool2option("allow-auto-record-incoming", v)); + final newValue = option2bool( + 'allow-auto-record-incoming', + await bind.mainGetOption( + key: 'allow-auto-record-incoming')); + setState(() { + _autoRecordIncomingSession = newValue; + }); + }, + ), + ], + ), SettingsSection( title: Text(translate("Share Screen")), tiles: shareScreenTiles, diff --git a/src/server/video_service.rs b/src/server/video_service.rs index d43996559..b583a0ae3 100644 --- a/src/server/video_service.rs +++ b/src/server/video_service.rs @@ -449,7 +449,7 @@ fn run(sp: GenericService) -> ResultType<()> { #[cfg(windows)] log::info!("gdi: {}", c.is_gdi()); let codec_name = Encoder::current_hw_encoder_name(); - #[cfg(not(any(target_os = "android", target_os = "ios")))] + #[cfg(not(target_os = "ios"))] let recorder = if !Config::get_option("allow-auto-record-incoming").is_empty() { Recorder::new(RecorderContext { id: "local".to_owned(), @@ -463,7 +463,7 @@ fn run(sp: GenericService) -> ResultType<()> { } else { Default::default() }; - #[cfg(any(target_os = "android", target_os = "ios"))] + #[cfg(target_os = "ios")] let recorder: Arc>> = Default::default(); #[cfg(windows)] start_uac_elevation_check(); @@ -674,7 +674,7 @@ fn handle_one_frame( let mut send_conn_ids: HashSet = Default::default(); if let Ok(msg) = encoder.encode_to_message(frame, ms) { - #[cfg(not(any(target_os = "android", target_os = "ios")))] + #[cfg(not(target_os = "ios"))] recorder .lock() .unwrap() diff --git a/src/ui_cm_interface.rs b/src/ui_cm_interface.rs index bd05f3bce..96fb84b6d 100644 --- a/src/ui_cm_interface.rs +++ b/src/ui_cm_interface.rs @@ -413,7 +413,7 @@ pub async fn start_listen( _ => {} } } - cm.remove_connection(current_id); + cm.remove_connection(current_id, true); } async fn handle_fs(fs: ipc::FS, write_jobs: &mut Vec, tx: &UnboundedSender) { diff --git a/src/ui_interface.rs b/src/ui_interface.rs index 9ef512fd7..142c9cb43 100644 --- a/src/ui_interface.rs +++ b/src/ui_interface.rs @@ -733,11 +733,21 @@ pub fn get_langs() -> String { #[inline] pub fn default_video_save_directory() -> String { let appname = crate::get_app_name(); + + #[cfg(any(target_os = "android", target_os = "ios"))] + if let Ok(home) = config::APP_HOME_DIR.read() { + let mut path = home.to_owned(); + path.push_str("/RustDesk/ScreenRecord"); + return path; + } + if let Some(user) = directories_next::UserDirs::new() { if let Some(video_dir) = user.video_dir() { return video_dir.join(appname).to_string_lossy().to_string(); } } + + #[cfg(not(any(target_os = "android", target_os = "ios")))] if let Some(home) = platform::get_active_user_home() { let name = if cfg!(target_os = "macos") { "Movies" @@ -746,6 +756,7 @@ pub fn default_video_save_directory() -> String { }; return home.join(name).join(appname).to_string_lossy().to_string(); } + if let Ok(exe) = std::env::current_exe() { if let Some(dir) = exe.parent() { return dir.join("videos").to_string_lossy().to_string();