move enter hook logic to service (where it belongs)

This commit is contained in:
Ferdinand Schober
2024-11-08 13:59:38 +01:00
parent 88693093c6
commit ff2a2cb1df
2 changed files with 46 additions and 38 deletions

View File

@@ -8,13 +8,9 @@ use futures::StreamExt;
use input_capture::{ use input_capture::{
CaptureError, CaptureEvent, CaptureHandle, InputCapture, InputCaptureError, Position, CaptureError, CaptureEvent, CaptureHandle, InputCapture, InputCaptureError, Position,
}; };
use lan_mouse_ipc::ClientHandle;
use lan_mouse_proto::ProtoEvent; use lan_mouse_proto::ProtoEvent;
use local_channel::mpsc::{channel, Receiver, Sender}; use local_channel::mpsc::{channel, Receiver, Sender};
use tokio::{ use tokio::task::{spawn_local, JoinHandle};
process::Command,
task::{spawn_local, JoinHandle},
};
use crate::{connect::LanMouseConnection, service::Service}; use crate::{connect::LanMouseConnection, service::Service};
@@ -28,11 +24,18 @@ pub(crate) struct Capture {
pub(crate) enum ICaptureEvent { pub(crate) enum ICaptureEvent {
/// a client was entered /// a client was entered
ClientEntered(CaptureHandle), CaptureBegin(CaptureHandle),
/// capture disabled /// capture disabled
CaptureDisabled, CaptureDisabled,
/// capture disabled /// capture disabled
CaptureEnabled, 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)] #[derive(Clone, Copy, Debug)]
@@ -309,7 +312,7 @@ async fn handle_capture_event(
if event == CaptureEvent::Begin { if event == CaptureEvent::Begin {
event_tx event_tx
.send(ICaptureEvent::ClientEntered(handle)) .send(ICaptureEvent::CaptureBegin(handle))
.expect("channel closed"); .expect("channel closed");
} }
@@ -331,8 +334,9 @@ async fn handle_capture_event(
if event == CaptureEvent::Begin && Some(handle) != active.get() { if event == CaptureEvent::Begin && Some(handle) != active.get() {
*state = State::WaitingForAck; *state = State::WaitingForAck;
active.replace(Some(handle)); active.replace(Some(handle));
log::info!("entering client {handle} ..."); event_tx
spawn_hook_command(service, handle); .send(ICaptureEvent::ClientEntered(handle))
.expect("channel closed");
} }
let pos = match service.client_manager.get_pos(handle) { let pos = match service.client_manager.get_pos(handle) {
@@ -345,7 +349,7 @@ async fn handle_capture_event(
CaptureEvent::Input(e) => match state { CaptureEvent::Input(e) => match state {
// connection not acknowledged, repeat `Enter` event // connection not acknowledged, repeat `Enter` event
State::WaitingForAck => ProtoEvent::Enter(pos), 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<CaptureRequest>) { async fn wait_for_termination(rx: &mut Receiver<CaptureRequest>) {
loop { loop {
match rx.recv().await.expect("channel closed") { match rx.recv().await.expect("channel closed") {

View File

@@ -24,7 +24,7 @@ use std::{
sync::{Arc, RwLock}, sync::{Arc, RwLock},
}; };
use thiserror::Error; use thiserror::Error;
use tokio::{signal, sync::Notify}; use tokio::{process::Command, signal, sync::Notify};
use webrtc_dtls::crypto::Certificate; use webrtc_dtls::crypto::Certificate;
#[derive(Debug, Error)] #[derive(Debug, Error)]
@@ -284,7 +284,7 @@ impl Service {
EmulationEvent::ReleaseNotify => capture.release(), EmulationEvent::ReleaseNotify => capture.release(),
}, },
event = capture.event() => match event { event = capture.event() => match event {
ICaptureEvent::ClientEntered(handle) => { ICaptureEvent::CaptureBegin(handle) => {
// we entered the capture zone for an incoming connection // we entered the capture zone for an incoming connection
// => notify it that its capture should be released // => notify it that its capture should be released
if let Some(incoming) = self.incoming_conn_info.borrow().get(&handle) { if let Some(incoming) = self.incoming_conn_info.borrow().get(&handle) {
@@ -299,6 +299,10 @@ impl Service {
self.capture_status.replace(Status::Enabled); self.capture_status.replace(Status::Enabled);
self.notify_frontend(FrontendEvent::CaptureStatus(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 { event = resolver.event() => match event {
DnsEvent::Resolving(handle) => self.set_resolving(handle, true), DnsEvent::Resolving(handle) => self.set_resolving(handle, true),
@@ -497,4 +501,30 @@ impl Service {
self.client_manager.set_resolving(handle, status); self.client_manager.set_resolving(handle, status);
self.client_updated(handle); 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}"),
}
});
}
} }