Files
achmad 14935db63e feat: implement ADB wrapper and device management backend
Adds full ADB client, device manager, static DeviceInfo fetcher, and
live DeviceLiveStats poller. Exposes ListDevices, ConnectDevice,
DisconnectDevice, GetDeviceInfo, GetDeviceLiveStats as Wails-bound
methods with a 1s devices:changed event loop. Bundles ADB binary
infrastructure via //go:embed all:bin with runtime fallback chain.
2026-05-06 14:51:34 +07:00

72 lines
1.4 KiB
Go

package adbembed
import (
"embed"
"fmt"
"os"
"path/filepath"
"runtime"
)
//go:embed all:bin
var binFS embed.FS
// Resolve returns the path to a usable adb binary.
// Order: embedded binary → ANDROID_HOME → PATH.
func Resolve() (string, error) {
if path, err := extractEmbedded(); err == nil {
return path, nil
}
return findOnSystem()
}
func extractEmbedded() (string, error) {
name := embeddedName()
data, err := binFS.ReadFile("bin/" + name)
if err != nil || len(data) < 1024 {
return "", fmt.Errorf("no embedded binary")
}
cacheDir, err := os.UserCacheDir()
if err != nil {
return "", err
}
dir := filepath.Join(cacheDir, "droidscope", "adb")
if err := os.MkdirAll(dir, 0755); err != nil {
return "", err
}
dest := filepath.Join(dir, adbExeName())
if err := os.WriteFile(dest, data, 0755); err != nil {
return "", err
}
return dest, nil
}
func findOnSystem() (string, error) {
if home := os.Getenv("ANDROID_HOME"); home != "" {
candidate := filepath.Join(home, "platform-tools", adbExeName())
if _, err := os.Stat(candidate); err == nil {
return candidate, nil
}
}
// Fall back to PATH
return findInPath()
}
func embeddedName() string {
os_ := runtime.GOOS
arch := runtime.GOARCH
if os_ == "windows" {
return fmt.Sprintf("adb-%s-%s.exe", os_, arch)
}
return fmt.Sprintf("adb-%s-%s", os_, arch)
}
func adbExeName() string {
if runtime.GOOS == "windows" {
return "adb.exe"
}
return "adb"
}