Skip to content

Commit

Permalink
feat: macos support
Browse files Browse the repository at this point in the history
  • Loading branch information
fax1ty committed Nov 12, 2024
1 parent 4fe0900 commit a1bbdd1
Show file tree
Hide file tree
Showing 9 changed files with 146 additions and 41 deletions.
Binary file modified bun.lockb
100644 → 100755
Binary file not shown.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@radix-ui/react-alert-dialog": "^1.1.2",
"@radix-ui/react-slot": "^1.1.0",
"@tauri-apps/api": "^2",
"@tauri-apps/plugin-os": "~2",
"@tauri-apps/plugin-process": "~2",
"@tauri-apps/plugin-shell": "~2",
"class-variance-authority": "^0.7.0",
Expand Down
78 changes: 78 additions & 0 deletions src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,10 @@ crate-type = ["staticlib", "cdylib", "rlib"]
tauri-build = { version = "2", features = [] }

[dependencies]
tauri = { version = "2", features = [] }
tauri = { version = "2", features = ["macos-private-api"] }
tauri-plugin-shell = "2"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
tauri-plugin-process = "2"
tauri-plugin-positioner = "2"
tauri-plugin-os = "2"
8 changes: 7 additions & 1 deletion src-tauri/capabilities/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@
"name": "cmd.exe",
"cmd": "cmd.exe",
"args": true
},
{
"name": "sh",
"cmd": "sh",
"args": true
}
]
},
"process:default"
"process:default",
"os:default"
]
}
1 change: 1 addition & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ fn get_android_home() -> Result<String, String> {
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_os::init())
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_shell::init())
.invoke_handler(tauri::generate_handler![get_android_home])
Expand Down
1 change: 1 addition & 0 deletions src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"frontendDist": "../dist"
},
"app": {
"macOSPrivateApi": true,
"windows": [
{
"title": "emu",
Expand Down
47 changes: 13 additions & 34 deletions src/services/api/emulator.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import { execute } from "@/services/execute";
import { adb, emulator } from "@/services/execute";
import {
OnlineEmulator,
OnlineEmulatorState,
OnlineEmulatorType,
} from "@/types/emulator";

export const getAllEmulators = async () => {
const output = await execute("cmd.exe", [
"/c",
"%ANDROID_HOME%/emulator/emulator.exe -list-avds",
]);
const output = await emulator("-list-avds");
return output
.split("\r\n")
.split("\n")
.map((v) => v.trim())
.filter((v) => {
if (!v) return false;
Expand All @@ -21,11 +18,8 @@ export const getAllEmulators = async () => {
};

export const getEmulatorName = async (id: string) => {
const output = await execute("cmd.exe", [
"/c",
`%ANDROID_HOME%/platform-tools/adb.exe -s ${id} emu avd name`,
]);
return output.split("\r\n").map((v) => v.trim())[0];
const output = await adb(`-s ${id} emu avd name`);
return output.split("\n").map((v) => v.trim())[0];
};

export const getEmulatorState = (
Expand All @@ -36,23 +30,17 @@ export const getEmulatorState = (
};

export const getEmulatorProps = async (id: string) => {
const output = await execute("cmd.exe", [
"/c",
`%ANDROID_HOME%/platform-tools/adb.exe -s ${id} shell getprop`,
]);
const kv = output.split("\r\n").map((v) => {
const output = await adb(`-s ${id} shell getprop`);
const kv = output.split("\n").map((v) => {
const [key, value] = v.replace(/(\[|\])/gm, "").split(": ");
return [key, value];
});
return Object.fromEntries(kv) as Record<string, string>;
};

export const getEmulatorFeatures = async (id: string) => {
const output = await execute("cmd.exe", [
"/c",
`%ANDROID_HOME%/platform-tools/adb.exe -s ${id} shell pm list features`,
]);
return output.split("\r\n");
const output = await adb("shell pm list features");
return output.split("\n");
};

export const getEmulatorType = (features: string[]): OnlineEmulatorType => {
Expand All @@ -63,12 +51,9 @@ export const getEmulatorType = (features: string[]): OnlineEmulatorType => {
};

export const getOnlineEmulators = async () => {
const output = await execute("cmd.exe", [
"/c",
"%ANDROID_HOME%/platform-tools/adb.exe devices -l",
]);
const output = await adb("devices -l");
const rows = output
.split("\r\n")
.split("\n")
.map((v) => v.trim())
.filter((v) => {
if (!v) return false;
Expand Down Expand Up @@ -116,15 +101,9 @@ export const startEmulator = async (name: string, cold = false) => {

if (cold) args.push("-no-snapshot-load");

await execute("cmd.exe", [
"/c",
`%ANDROID_HOME%/emulator/emulator.exe ` + args.join(" "),
]);
await emulator(args.join(" "));
};

export const stopEmulator = async (id: string) => {
await execute("cmd.exe", [
"/c",
`%ANDROID_HOME%/platform-tools/adb.exe -s ${id} emu kill`,
]);
await adb(`-s ${id} emu kill`);
};
48 changes: 43 additions & 5 deletions src/services/execute.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,41 @@
import { platform } from "@tauri-apps/plugin-os";
import { Command, type SpawnOptions } from "@tauri-apps/plugin-shell";

const getAndroidHomePrefix = () => {
const currentPlatfrom = platform();

switch (currentPlatfrom) {
case "windows":
return "%ANDROID_HOME";

default:
return "$ANDROID_HOME";
}
};

const makeCommand = (executable: string, ...args: string[]) => {
const currentPlatfrom = platform();

switch (currentPlatfrom) {
case "windows":
return Command.create("cmd.exe", [
"/c",
executable + ".exe " + args.join(" "),
]);

default:
return Command.create("sh", ["-c", executable + " " + args.join(" ")]);
}
};

export const execute = async (
base: string,
args?: string | string[],
executable: string,
args: string[] = [],
options?: SpawnOptions & { timeout?: number; verbose?: boolean }
) => {
const cmd = Command.create(base, args, options);
const cmd = makeCommand(executable, ...args);
cmd.stdout.on("data", (v) => {
if (options?.verbose) console.info(base, args, v);
if (options?.verbose) console.info(executable, args, v);
});
if (typeof options?.timeout === "number") {
setTimeout(() => {
Expand All @@ -16,5 +44,15 @@ export const execute = async (
}

const process = await cmd.execute();
return process.stdout;
return process.stdout.replace(/\r/gm, "");
};

export const emulator = (command: string) => {
const prefix = getAndroidHomePrefix();
return execute(`${prefix}/emulator/emulator`, [command]);
};

export const adb = (command: string) => {
const prefix = getAndroidHomePrefix();
return execute(`${prefix}/platform-tools/adb`, [command]);
};

0 comments on commit a1bbdd1

Please sign in to comment.