From ff2a2cb1df411dcb4a100f4bdc45a0511d6696bb Mon Sep 17 00:00:00 2001 From: Ferdinand Schober Date: Fri, 8 Nov 2024 13:59:38 +0100 Subject: [PATCH] move enter hook logic to service (where it belongs) --- src/capture.rs | 50 ++++++++++++++------------------------------------ src/service.rs | 34 ++++++++++++++++++++++++++++++++-- 2 files changed, 46 insertions(+), 38 deletions(-) diff --git a/src/capture.rs b/src/capture.rs index cae5b1d..3287ed0 100644 --- a/src/capture.rs +++ b/src/capture.rs @@ -8,13 +8,9 @@ use futures::StreamExt; use input_capture::{ CaptureError, CaptureEvent, CaptureHandle, InputCapture, InputCaptureError, Position, }; -use lan_mouse_ipc::ClientHandle; use lan_mouse_proto::ProtoEvent; use local_channel::mpsc::{channel, Receiver, Sender}; -use tokio::{ - process::Command, - task::{spawn_local, JoinHandle}, -}; +use tokio::task::{spawn_local, JoinHandle}; use crate::{connect::LanMouseConnection, service::Service}; @@ -28,11 +24,18 @@ pub(crate) struct Capture { pub(crate) enum ICaptureEvent { /// a client was entered - ClientEntered(CaptureHandle), + CaptureBegin(CaptureHandle), /// capture disabled CaptureDisabled, /// capture disabled CaptureEnabled, + /// A (new) client was entered. + /// In contrast to [`ICaptureEvent::CaptureBegin`] this + /// event is only triggered when the capture was + /// explicitly released in the meantime by + /// either the remote client leaving its device region, + /// a new device entering the screen or the release bind. + ClientEntered(u64), } #[derive(Clone, Copy, Debug)] @@ -309,7 +312,7 @@ async fn handle_capture_event( if event == CaptureEvent::Begin { event_tx - .send(ICaptureEvent::ClientEntered(handle)) + .send(ICaptureEvent::CaptureBegin(handle)) .expect("channel closed"); } @@ -331,8 +334,9 @@ async fn handle_capture_event( if event == CaptureEvent::Begin && Some(handle) != active.get() { *state = State::WaitingForAck; active.replace(Some(handle)); - log::info!("entering client {handle} ..."); - spawn_hook_command(service, handle); + event_tx + .send(ICaptureEvent::ClientEntered(handle)) + .expect("channel closed"); } let pos = match service.client_manager.get_pos(handle) { @@ -345,7 +349,7 @@ async fn handle_capture_event( CaptureEvent::Input(e) => match state { // connection not acknowledged, repeat `Enter` event State::WaitingForAck => ProtoEvent::Enter(pos), - _ => ProtoEvent::Input(e), + State::Sending => ProtoEvent::Input(e), }, }; @@ -383,32 +387,6 @@ fn to_proto_pos(pos: lan_mouse_ipc::Position) -> lan_mouse_proto::Position { } } -fn spawn_hook_command(service: &Service, handle: ClientHandle) { - let Some(cmd) = service.client_manager.get_enter_cmd(handle) else { - return; - }; - tokio::task::spawn_local(async move { - log::info!("spawning command!"); - let mut child = match Command::new("sh").arg("-c").arg(cmd.as_str()).spawn() { - Ok(c) => c, - Err(e) => { - log::warn!("could not execute cmd: {e}"); - return; - } - }; - match child.wait().await { - Ok(s) => { - if s.success() { - log::info!("{cmd} exited successfully"); - } else { - log::warn!("{cmd} exited with {s}"); - } - } - Err(e) => log::warn!("{cmd}: {e}"), - } - }); -} - async fn wait_for_termination(rx: &mut Receiver) { loop { match rx.recv().await.expect("channel closed") { diff --git a/src/service.rs b/src/service.rs index 2240388..42c1911 100644 --- a/src/service.rs +++ b/src/service.rs @@ -24,7 +24,7 @@ use std::{ sync::{Arc, RwLock}, }; use thiserror::Error; -use tokio::{signal, sync::Notify}; +use tokio::{process::Command, signal, sync::Notify}; use webrtc_dtls::crypto::Certificate; #[derive(Debug, Error)] @@ -284,7 +284,7 @@ impl Service { EmulationEvent::ReleaseNotify => capture.release(), }, event = capture.event() => match event { - ICaptureEvent::ClientEntered(handle) => { + ICaptureEvent::CaptureBegin(handle) => { // we entered the capture zone for an incoming connection // => notify it that its capture should be released if let Some(incoming) = self.incoming_conn_info.borrow().get(&handle) { @@ -299,6 +299,10 @@ impl Service { self.capture_status.replace(Status::Enabled); self.notify_frontend(FrontendEvent::CaptureStatus(Status::Enabled)); } + ICaptureEvent::ClientEntered(handle) => { + log::info!("entering client {handle} ..."); + self.spawn_hook_command(handle) + }, }, event = resolver.event() => match event { DnsEvent::Resolving(handle) => self.set_resolving(handle, true), @@ -497,4 +501,30 @@ impl Service { self.client_manager.set_resolving(handle, status); self.client_updated(handle); } + + fn spawn_hook_command(&self, handle: ClientHandle) { + let Some(cmd) = self.client_manager.get_enter_cmd(handle) else { + return; + }; + tokio::task::spawn_local(async move { + log::info!("spawning command!"); + let mut child = match Command::new("sh").arg("-c").arg(cmd.as_str()).spawn() { + Ok(c) => c, + Err(e) => { + log::warn!("could not execute cmd: {e}"); + return; + } + }; + match child.wait().await { + Ok(s) => { + if s.success() { + log::info!("{cmd} exited successfully"); + } else { + log::warn!("{cmd} exited with {s}"); + } + } + Err(e) => log::warn!("{cmd}: {e}"), + } + }); + } }