diff --git a/src-tauri/src/adb.rs b/src-tauri/src/adb.rs index 6206ef8..19fc408 100644 --- a/src-tauri/src/adb.rs +++ b/src-tauri/src/adb.rs @@ -58,6 +58,27 @@ impl Device { .spawn() .context("Failed to execute 'adb shell'")?) } + + /// execute "adb shell wm size" to get screen size + pub fn cmd_screen_size(res_dir: &PathBuf, id: &str) -> Result<(u32, u32)> { + let mut adb_command = Adb::cmd_base(res_dir); + let output = adb_command + .args(&["-s", id, "shell", "wm", "size"]) + .output() + .context("Failed to execute 'adb shell wm size'")?; + + for line in output.stdout.lines() { + if let std::result::Result::Ok(line) = line { + if line.starts_with("Physical size: ") { + let size_str = line.trim_start_matches("Physical size: ").split('x'); + let width = size_str.clone().next().unwrap().parse::().unwrap(); + let height = size_str.clone().last().unwrap().parse::().unwrap(); + return Ok((width, height)); + } + } + }; + Err(anyhow::anyhow!("Failed to get screen size")) + } } pub struct Adb; diff --git a/src-tauri/src/client.rs b/src-tauri/src/client.rs index 27a0ba2..ebb59a1 100644 --- a/src-tauri/src/client.rs +++ b/src-tauri/src/client.rs @@ -40,6 +40,11 @@ impl ScrcpyClient { Adb::cmd_forward_remove(res_dir) } + // get the screen size of the device + pub fn get_device_screen_size(res_dir: &PathBuf, id: &str) -> Result<(u32, u32)> { + Device::cmd_screen_size(res_dir, id) + } + /// push server file to current device pub fn push_server_file(res_dir: &PathBuf, id: &str) -> Result<()> { let info = Device::cmd_push( diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 6025826..7ec4485 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -108,6 +108,15 @@ fn start_scrcpy_server( Ok(()) } +#[tauri::command] +fn get_device_screen_size(id: String, app: tauri::AppHandle) -> Result<(u32, u32), String> { + let dir = app.path().resource_dir().unwrap().join("resource"); + match ScrcpyClient::get_device_screen_size(&dir, &id) { + Ok(size) => Ok(size), + Err(e) => Err(e.to_string()), + } +} + #[tauri::command] fn load_default_keyconfig(app: tauri::AppHandle) -> Result { let dir = app.path().resource_dir().unwrap().join("resource"); @@ -194,6 +203,7 @@ async fn main() { forward_server_port, push_server_file, start_scrcpy_server, + get_device_screen_size, load_default_keyconfig ]) .run(tauri::generate_context!()) diff --git a/src/components/Device.vue b/src/components/Device.vue index c790f6c..136d6a0 100644 --- a/src/components/Device.vue +++ b/src/components/Device.vue @@ -15,6 +15,7 @@ import { pushServerFile, forwardServerPort, startScrcpyServer, + getDeviceScreenSize, } from "../invoke"; import { NH4, @@ -160,74 +161,92 @@ const menuOptions: DropdownOption[] = [ label: () => h("span", "控制此设备"), key: "control", }, + { + label: () => h("span", "获取屏幕尺寸"), + key: "screen", + }, ]; function onMenuClickoutside() { showMenu.value = false; } +async function deviceControl() { + if (!port.value) { + port.value = 27183; + } + + if (!(store.screenSizeW > 0) || !(store.screenSizeH > 0)) { + message.error("请正确输入当前控制设备的屏幕尺寸"); + store.screenSizeW = 0; + store.screenSizeH = 0; + store.hideLoading(); + return; + } + + if (store.controledDevice) { + message.error("请先关闭当前控制设备"); + store.hideLoading(); + return; + } + + localStore.set("screenSize", { + sizeW: store.screenSizeW, + sizeH: store.screenSizeH, + }); + message.info("屏幕尺寸已保存,正在启动控制服务,请保持设备亮屏"); + + const device = devices.value[rowIndex]; + + let scid = ( + "00000000" + Math.floor(Math.random() * 100000).toString(16) + ).slice(-8); + + await pushServerFile(device.id); + await forwardServerPort(device.id, scid, port.value); + await startScrcpyServer(device.id, scid, `127.0.0.1:${port.value}`); + + // connection timeout check + let id = setTimeout(async () => { + if (deviceWaitForMetadataTask) { + await shutdown(); + store.controledDevice = null; + store.hideLoading(); + message.error("设备连接超时"); + } + }, 6000); + + // add cb for metadata + deviceWaitForMetadataTask = (deviceName: string) => { + store.controledDevice = { + scid, + deviceName, + device, + }; + nextTick(() => { + deviceWaitForMetadataTask = null; + clearTimeout(id); + store.hideLoading(); + }); + }; +} + +async function deviceGetScreenSize() { + let id = devices.value[rowIndex].id; + const size = await getDeviceScreenSize(id); + store.hideLoading(); + message.success(`设备屏幕尺寸为: ${size[0]} x ${size[1]}`); +} + async function onMenuSelect(key: string) { showMenu.value = false; store.showLoading(); switch (key) { case "control": - if (!port.value) { - port.value = 27183; - } - - if (!(store.screenSizeW > 0) || !(store.screenSizeH > 0)) { - message.error("请正确输入当前控制设备的屏幕尺寸"); - store.screenSizeW = 0; - store.screenSizeH = 0; - store.hideLoading(); - return; - } - - if (store.controledDevice) { - message.error("请先关闭当前控制设备"); - store.hideLoading(); - return; - } - - localStore.set("screenSize", { - sizeW: store.screenSizeW, - sizeH: store.screenSizeH, - }); - message.info("屏幕尺寸已保存,正在启动控制服务,请保持设备亮屏"); - - let device = devices.value[rowIndex]; - - let scid = ( - "00000000" + Math.floor(Math.random() * 100000).toString(16) - ).slice(-8); - - await pushServerFile(device.id); - await forwardServerPort(device.id, scid, port.value); - await startScrcpyServer(device.id, scid, `127.0.0.1:${port.value}`); - - // connection timeout check - let id = setTimeout(async () => { - if (deviceWaitForMetadataTask) { - await shutdown(); - store.controledDevice = null; - store.hideLoading(); - message.error("设备连接超时"); - } - }, 6000); - - // add cb for metadata - deviceWaitForMetadataTask = (deviceName: string) => { - store.controledDevice = { - scid, - deviceName, - device, - }; - nextTick(() => { - deviceWaitForMetadataTask = null; - clearTimeout(id); - store.hideLoading(); - }); - }; + await deviceControl(); + break; + case "screen": + await deviceGetScreenSize(); break; } } @@ -297,7 +316,7 @@ async function refreshDevices() { scid: {{ store.controledDevice.scid }}
status: - {{ store.controledDevice.device.status }}
screen: + {{ store.controledDevice.device.status }}