simple privacy demo
Signed-off-by: fufesou <shuanglongchen@yeah.net>
This commit is contained in:
		
							parent
							
								
									8f998771c9
								
							
						
					
					
						commit
						a1c4b08535
					
				| @ -1013,11 +1013,10 @@ fn run_cmds(cmds: String, show: bool) -> ResultType<()> { | ||||
|     Ok(()) | ||||
| } | ||||
| 
 | ||||
| pub fn toggle_privacy_mode(v: bool) { | ||||
| pub fn toggle_blank_screen(v: bool) { | ||||
|     let v = if v { TRUE } else { FALSE }; | ||||
|     unsafe { | ||||
|         blank_screen(v); | ||||
|         BlockInput(v); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -15,6 +15,7 @@ use hbb_common::{ | ||||
|     tokio_util::codec::{BytesCodec, Framed}, | ||||
| }; | ||||
| use sha2::{Digest, Sha256}; | ||||
| use std::sync::mpsc::{sync_channel, Receiver, SyncSender}; | ||||
| 
 | ||||
| pub type Sender = mpsc::UnboundedSender<(Instant, Arc<Message>)>; | ||||
| 
 | ||||
| @ -84,6 +85,14 @@ const MILLI1: Duration = Duration::from_millis(1); | ||||
| const SEND_TIMEOUT_VIDEO: u64 = 12_000; | ||||
| const SEND_TIMEOUT_OTHER: u64 = SEND_TIMEOUT_VIDEO * 10; | ||||
| 
 | ||||
| type SyncFunc = Box<dyn Send + FnMut()>; | ||||
| 
 | ||||
| enum BlankChannelMsg { | ||||
|     On, | ||||
|     Off, | ||||
|     Exit, | ||||
| } | ||||
| 
 | ||||
| impl Connection { | ||||
|     pub async fn start( | ||||
|         addr: SocketAddr, | ||||
| @ -157,6 +166,12 @@ impl Connection { | ||||
|             }, | ||||
|         ); | ||||
| 
 | ||||
|         let (input_sender, input_receiver) = sync_channel(1); | ||||
| 
 | ||||
|         let (blank_sender, blank_receiver) = sync_channel(1); | ||||
|         let _ = std::thread::spawn(move || Self::handle_input(input_receiver)); | ||||
|         let blank_handler = std::thread::spawn(move || Self::handle_blank(blank_receiver)); | ||||
| 
 | ||||
|         loop { | ||||
|             tokio::select! { | ||||
|                 biased; // video has higher priority
 | ||||
| @ -232,7 +247,7 @@ impl Connection { | ||||
|                             Ok(bytes) => { | ||||
|                                 last_recv_time = Instant::now(); | ||||
|                                 if let Ok(msg_in) = Message::parse_from_bytes(&bytes) { | ||||
|                                     if !conn.on_message(msg_in).await { | ||||
|                                     if !conn.on_message(msg_in, input_sender.clone(), blank_sender.clone()).await { | ||||
|                                         break; | ||||
|                                     } | ||||
|                                 } | ||||
| @ -297,6 +312,14 @@ impl Connection { | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         blank_sender.send(BlankChannelMsg::Exit).unwrap(); | ||||
|         if let Err(e) = blank_handler.join() { | ||||
|             log::error!("Failed to join blank thread, {:?}", e); | ||||
|         }; | ||||
| 
 | ||||
|         crate::platform::block_input(false); | ||||
|         crate::platform::toggle_blank_screen(false); | ||||
| 
 | ||||
|         video_service::notify_video_frame_feched(id, None); | ||||
|         super::video_service::update_test_latency(id, 0); | ||||
|         super::video_service::update_image_quality(id, None); | ||||
| @ -305,6 +328,44 @@ impl Connection { | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     // TODO:
 | ||||
|     // 1. Send "Block Input" and "Privacy Mode" when connection established.
 | ||||
|     // 2. Ctrl + Alt + Del will break "Block Input"
 | ||||
|     fn handle_input(receiver: Receiver<SyncFunc>) { | ||||
|         loop { | ||||
|             match receiver.recv() { | ||||
|                 Ok(mut f) => { | ||||
|                     f(); | ||||
|                 } | ||||
|                 _ => break, | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn handle_blank(receiver: Receiver<BlankChannelMsg>) { | ||||
|         let mut last_privacy = false; | ||||
|         loop { | ||||
|             match receiver.recv_timeout(std::time::Duration::from_millis(500)) { | ||||
|                 Ok(v) => match v { | ||||
|                     BlankChannelMsg::On => { | ||||
|                         crate::platform::toggle_blank_screen(true); | ||||
|                         last_privacy = true; | ||||
|                     } | ||||
|                     BlankChannelMsg::Off => { | ||||
|                         crate::platform::toggle_blank_screen(false); | ||||
|                         last_privacy = false; | ||||
|                     } | ||||
|                     _ => break, | ||||
|                 }, | ||||
|                 _ => { | ||||
|                     if last_privacy { | ||||
|                         crate::platform::toggle_blank_screen(true); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     async fn try_port_forward_loop( | ||||
|         &mut self, | ||||
|         rx_from_cm: &mut mpsc::UnboundedReceiver<Data>, | ||||
| @ -536,10 +597,15 @@ impl Connection { | ||||
|         self.send(msg_out).await; | ||||
|     } | ||||
| 
 | ||||
|     async fn on_message(&mut self, msg: Message) -> bool { | ||||
|     async fn on_message( | ||||
|         &mut self, | ||||
|         msg: Message, | ||||
|         input_sender: SyncSender<SyncFunc>, | ||||
|         blank_sender: SyncSender<BlankChannelMsg>, | ||||
|     ) -> bool { | ||||
|         if let Some(message::Union::login_request(lr)) = msg.union { | ||||
|             if let Some(o) = lr.option.as_ref() { | ||||
|                 self.update_option(o); | ||||
|                 self.update_option(o, input_sender, blank_sender); | ||||
|             } | ||||
|             if self.authorized { | ||||
|                 return true; | ||||
| @ -654,7 +720,8 @@ impl Connection { | ||||
|             match msg.union { | ||||
|                 Some(message::Union::mouse_event(me)) => { | ||||
|                     if self.keyboard { | ||||
|                         handle_mouse(&me, self.inner.id()); | ||||
|                         let conn_id = self.inner.id(); | ||||
|                         input_sender.send(Box::new(move || handle_mouse(&me, conn_id))).unwrap(); | ||||
|                     } | ||||
|                 } | ||||
|                 Some(message::Union::key_event(mut me)) => { | ||||
| @ -669,17 +736,19 @@ impl Connection { | ||||
|                         }; | ||||
|                         if is_press { | ||||
|                             if let Some(key_event::Union::unicode(_)) = me.union { | ||||
|                                 handle_key(&me); | ||||
|                                 input_sender.send(Box::new(move || handle_key(&me))).unwrap(); | ||||
|                             } else if let Some(key_event::Union::seq(_)) = me.union { | ||||
|                                 handle_key(&me); | ||||
|                                 input_sender.send(Box::new(move || handle_key(&me))).unwrap(); | ||||
|                             } else { | ||||
|                                 me.down = true; | ||||
|                                 handle_key(&me); | ||||
|                                 me.down = false; | ||||
|                                 handle_key(&me); | ||||
|                                 input_sender.send(Box::new(move || { | ||||
|                                     me.down = true; | ||||
|                                     handle_key(&me); | ||||
|                                     me.down = false; | ||||
|                                     handle_key(&me); | ||||
|                                 })).unwrap(); | ||||
|                             } | ||||
|                         } else { | ||||
|                             handle_key(&me); | ||||
|                             input_sender.send(Box::new(move || handle_key(&me))).unwrap(); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| @ -782,7 +851,7 @@ impl Connection { | ||||
|                         self.send_to_cm(ipc::Data::ChatMessage { text: c.text }); | ||||
|                     } | ||||
|                     Some(misc::Union::option(o)) => { | ||||
|                         self.update_option(&o); | ||||
|                         self.update_option(&o, input_sender, blank_sender); | ||||
|                     } | ||||
|                     Some(misc::Union::refresh_video(r)) => { | ||||
|                         if r { | ||||
| @ -797,7 +866,12 @@ impl Connection { | ||||
|         true | ||||
|     } | ||||
| 
 | ||||
|     fn update_option(&mut self, o: &OptionMessage) { | ||||
|     fn update_option( | ||||
|         &mut self, | ||||
|         o: &OptionMessage, | ||||
|         input_sender: SyncSender<SyncFunc>, | ||||
|         blank_sender: SyncSender<BlankChannelMsg>, | ||||
|     ) { | ||||
|         log::info!("Option update: {:?}", o); | ||||
|         if let Ok(q) = o.image_quality.enum_value() { | ||||
|             self.image_quality = q.value(); | ||||
| @ -857,15 +931,23 @@ impl Connection { | ||||
|         if let Ok(q) = o.privacy_mode.enum_value() { | ||||
|             if q != BoolOption::NotSet { | ||||
|                 self.privacy_mode = q == BoolOption::Yes; | ||||
|                 if self.privacy_mode && self.keyboard { | ||||
|                     crate::platform::toggle_privacy_mode(true); | ||||
|                 if self.keyboard { | ||||
|                     if self.privacy_mode { | ||||
|                         input_sender.send(Box::new(move||{crate::platform::block_input(true)})).unwrap(); | ||||
|                         blank_sender.send(BlankChannelMsg::On).unwrap(); | ||||
|                     } else { | ||||
|                         input_sender.send(Box::new(move||{crate::platform::block_input(false)})).unwrap(); | ||||
|                         blank_sender.send(BlankChannelMsg::Off).unwrap(); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if self.keyboard { | ||||
|             if let Ok(q) = o.block_input.enum_value() { | ||||
|                 if q != BoolOption::NotSet { | ||||
|                     crate::platform::block_input(q == BoolOption::Yes); | ||||
|                     input_sender.send(Box::new(move || { | ||||
|                         crate::platform::block_input(q == BoolOption::Yes) | ||||
|                     })).unwrap(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| @ -880,9 +962,6 @@ impl Connection { | ||||
|             crate::platform::lock_screen(); | ||||
|             super::video_service::switch_to_primary(); | ||||
|         } | ||||
|         if self.privacy_mode { | ||||
|             crate::platform::toggle_privacy_mode(false); | ||||
|         } | ||||
|         self.port_forward_socket.take(); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -130,7 +130,8 @@ class Header: Reactor.Component { | ||||
|                 {audio_enabled ? <li #disable-audio .toggle-option><span>{svg_checkmark}</span>{translate('Mute')}</li> : ""} | ||||
|                 {keyboard_enabled && clipboard_enabled ? <li #disable-clipboard .toggle-option><span>{svg_checkmark}</span>{translate('Disable clipboard')}</li> : ""}  | ||||
|                 {keyboard_enabled ? <li #lock-after-session-end .toggle-option><span>{svg_checkmark}</span>{translate('Lock after session end')}</li> : ""}  | ||||
|                 {false && pi.platform == "Windows" ? <li #privacy-mode .toggle-option><span>{svg_checkmark}</span>{translate('Privacy mode')}</li> : ""} | ||||
|                 {pi.platform == "Windows" ? <li #block-input>Block user input </li> : ""} | ||||
|                 {pi.platform == "Windows" ? <li #privacy-mode .toggle-option><span>{svg_checkmark}</span>{translate('Privacy mode')}</li> : ""} | ||||
|             </menu> | ||||
|         </popup>; | ||||
|     } | ||||
| @ -144,7 +145,7 @@ class Header: Reactor.Component { | ||||
|                 {keyboard_enabled && (pi.platform == "Linux" || pi.sas_enabled) ? <li #ctrl-alt-del>{translate('Insert')} Ctrl + Alt + Del</li> : ""} | ||||
|                 <div .separator /> | ||||
|                 {keyboard_enabled ? <li #lock-screen>{translate('Insert Lock')}</li> : ""} | ||||
|                 {false && pi.platform == "Windows" ? <li #block-input>Block user input </li> : ""} | ||||
|                 {pi.platform == "Windows" ? <li #block-input>Block user input </li> : ""} | ||||
|                 {handler.support_refresh() ? <li #refresh>{translate('Refresh')}</li> : ""} | ||||
|             </menu> | ||||
|         </popup>; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user