diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index c35b8ff..69d93a2 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -16,6 +16,7 @@ tauri-plugin-store = "2.0.0-beta" serde = { version = "1", features = ["derive"] } serde_json = "1" anyhow = "1.0" +lazy_static = "1.4.0" tokio = { version = "1.36.0", features = ["rt-multi-thread", "net", "macros", "io-util", "time", "sync"] } tauri-plugin-process = "2.0.0-beta" tauri-plugin-shell = "2.0.0-beta" diff --git a/src-tauri/src/client.rs b/src-tauri/src/client.rs index ebb59a1..85bbc28 100644 --- a/src-tauri/src/client.rs +++ b/src-tauri/src/client.rs @@ -3,7 +3,7 @@ use std::{io::BufRead, path::PathBuf}; use crate::{ adb::{Adb, Device}, - resource::{ResHelper, ResourceName}, + resource::{ResHelper, ResourceName}, share, }; /** @@ -119,6 +119,8 @@ impl ScrcpyClient { // clear string to store new line only s.clear(); } + + *share::CLIENT_INFO.lock().unwrap() = None; println!("Scrcpy server closed"); Ok(()) } diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 120ab6b..85eb83b 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -5,3 +5,4 @@ pub mod control_msg; pub mod resource; pub mod scrcpy_mask_cmd; pub mod socket; +pub mod share; diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index b31b9ae..4347073 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -5,6 +5,7 @@ use scrcpy_mask::{ adb::{Adb, Device}, client::ScrcpyClient, resource::{ResHelper, ResourceName}, + share, socket::connect_socket, }; use std::{fs::read_to_string, sync::Arc}; @@ -54,6 +55,17 @@ fn start_scrcpy_server( address: String, app: tauri::AppHandle, ) -> Result<(), String> { + let mut client_info = share::CLIENT_INFO.lock().unwrap(); + if let Some(_) = &*client_info { + return Err("client already exists".to_string()); + } + + *client_info = Some(share::ClientInfo::new( + "unknow".to_string(), + id.clone(), + scid.clone(), + )); + let dir = app.path().resource_dir().unwrap().join("resource"); let version = ScrcpyClient::get_scrcpy_version(); @@ -108,6 +120,15 @@ fn start_scrcpy_server( Ok(()) } +#[tauri::command] +fn get_cur_client_info() -> Result, String> { + let client_info = share::CLIENT_INFO.lock().unwrap(); + match &*client_info { + Some(client) => Ok(Some(client.clone())), + None => Ok(None), + } +} + #[tauri::command] /// get device screen size fn get_device_screen_size(id: String, app: tauri::AppHandle) -> Result<(u32, u32), String> { @@ -217,6 +238,7 @@ async fn main() { forward_server_port, push_server_file, start_scrcpy_server, + get_cur_client_info, get_device_screen_size, adb_connect, load_default_keyconfig diff --git a/src-tauri/src/share.rs b/src-tauri/src/share.rs new file mode 100644 index 0000000..74173fa --- /dev/null +++ b/src-tauri/src/share.rs @@ -0,0 +1,23 @@ +use lazy_static::lazy_static; +use std::sync::Mutex; + +#[derive(Debug, Clone, serde::Serialize)] +pub struct ClientInfo { + pub device_name: String, + pub device_id: String, + pub scid: String, +} + +impl ClientInfo { + pub fn new(device_name: String, device_id: String, scid: String) -> Self { + Self { + device_name, + device_id, + scid, + } + } +} + +lazy_static! { + pub static ref CLIENT_INFO: Mutex> = Mutex::new(None); +} diff --git a/src-tauri/src/socket.rs b/src-tauri/src/socket.rs index 8a1df23..5c53396 100644 --- a/src-tauri/src/socket.rs +++ b/src-tauri/src/socket.rs @@ -13,6 +13,7 @@ use tokio::{ use crate::{ control_msg::{self, ControlMsgType}, scrcpy_mask_cmd::{self, ScrcpyMaskCmdType}, + share, }; pub async fn connect_socket( @@ -26,7 +27,7 @@ pub async fn connect_socket( .await .context("Socket connect failed")?; - println!("成功连接scrcpy-server:{:?}", client.local_addr()); + println!("connect to scrcpy-server:{:?}", client.local_addr()); let (read_half, write_half) = client.into_split(); @@ -71,6 +72,9 @@ async fn read_socket( end -= 1; } let device_name = std::str::from_utf8(&buf[..end]).unwrap(); + // update device name for share + share::CLIENT_INFO.lock().unwrap().as_mut().unwrap().device_name = device_name.to_string(); + let msg = json!({ "type": "MetaData", "deviceName": device_name, diff --git a/src/components/Device.vue b/src/components/Device.vue index 93ead1b..c14d544 100644 --- a/src/components/Device.vue +++ b/src/components/Device.vue @@ -17,6 +17,7 @@ import { startScrcpyServer, getDeviceScreenSize, adbConnect, + getCurClientInfo, } from "../invoke"; import { NH4, @@ -86,6 +87,26 @@ onMounted(async () => { }); onActivated(async () => { + let curClientInfo = await getCurClientInfo(); + if (store.controledDevice) { + // update controledDevice if client not exists + if (!curClientInfo) { + await shutdown(); + store.controledDevice = null; + message.warning(t("pages.Device.alreadyDisconnected")); + } + } else { + // restore controledDevice if client exists + if (curClientInfo) { + message.warning(t("pages.Device.alreadyControled")); + store.controledDevice = { + scid: curClientInfo.scid, + deviceName: curClientInfo.device_name, + deviceID: curClientInfo.device_id, + }; + } + } + await refreshDevices(); }); @@ -178,6 +199,18 @@ function onMenuClickoutside() { } async function deviceControl() { + let curClientInfo = await getCurClientInfo(); + if (curClientInfo) { + message.warning(t("pages.Device.alreadyControled")); + store.controledDevice = { + scid: curClientInfo.scid, + deviceName: curClientInfo.device_name, + deviceID: curClientInfo.device_id, + }; + store.hideLoading(); + return; + } + if (!port.value) { port.value = 27183; } diff --git a/src/i18n/en-US.json b/src/i18n/en-US.json index 9d5ffda..0f0873e 100644 --- a/src/i18n/en-US.json +++ b/src/i18n/en-US.json @@ -35,7 +35,9 @@ }, "controledDevice": "Controlled device", "availableDevice": "Available devices", - "noControledDevice": "No Controled Device" + "noControledDevice": "No Controled Device", + "alreadyControled": "Controlled device already exists", + "alreadyDisconnected": "Controlled device connection has been disconnected" }, "Mask": { "inputBoxPlaceholder": "Input text and then press enter/esc", diff --git a/src/i18n/zh-CN.json b/src/i18n/zh-CN.json index 425e53c..2952d5c 100644 --- a/src/i18n/zh-CN.json +++ b/src/i18n/zh-CN.json @@ -35,7 +35,9 @@ }, "controledDevice": "受控设备", "noControledDevice": "无受控设备", - "availableDevice": "可用设备" + "availableDevice": "可用设备", + "alreadyControled": "已存在受控设备", + "alreadyDisconnected": "受控设备连接已断开" }, "Mask": { "keyconfigException": "按键方案异常,请删除此方案", diff --git a/src/invoke.ts b/src/invoke.ts index 9c7f157..98f335c 100644 --- a/src/invoke.ts +++ b/src/invoke.ts @@ -29,6 +29,14 @@ export async function startScrcpyServer( return await invoke("start_scrcpy_server", { id, scid, address }); } +export async function getCurClientInfo(): Promise<{ + device_name: string; + device_id: string; + scid: string; +} | null> { + return await invoke("get_cur_client_info"); +} + export async function getDeviceScreenSize( id: string ): Promise<[number, number]> {