Skip to content

Commit

Permalink
Handle serial number option and raise issue if multiple devices conne…
Browse files Browse the repository at this point in the history
…cted
  • Loading branch information
Te-k committed Jan 25, 2024
1 parent 163d761 commit b94438a
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 10 deletions.
72 changes: 67 additions & 5 deletions adb/adb.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,19 @@ import (
"os/exec"
"strings"

saveSlice "github.com/botherder/go-savetime/slice"
"github.com/mvt-project/androidqf/log"
)

type ADB struct {
ExePath string
Serial string
}

var Client *ADB

// New returns a new ADB instance.
func New() (*ADB, error) {
func New(serial string) (*ADB, error) {
adb := ADB{}
err := adb.findExe()
if err != nil {
Expand All @@ -32,15 +34,75 @@ func New() (*ADB, error) {

log.Debug("Killing existing ADB server if running")
adb.KillServer()

// Managing devices
devices, err := adb.Devices()
if err != nil {
return nil, err
}

serial = strings.TrimSpace(serial)
if len(devices) == 0 {
return nil, fmt.Errorf("no devices connected to adb")
}
if serial != "" {
// Check that the serial match one of the devices
// Can be replace with the go package slices in 1.21
if !saveSlice.ContainsNoCase(devices, serial) {
// Serial is not an existing device
return nil, fmt.Errorf("serial %s not found in the device list", serial)
}
adb.Serial = serial
} else {
// Problem if multiple devices
if len(devices) > 1 {
return nil, fmt.Errorf("multiple devices connected, please provide a serial number")
}
adb.Serial = ""
}

return &adb, nil
}

// List existing devices
func (a *ADB) Devices() ([]string, error) {
var devices []string
out, err := exec.Command(a.ExePath, "devices").Output()
if err != nil {
return devices, fmt.Errorf("failed to use the adb executable: %v",
err)
}

lines := strings.Split(string(out), "\n")
for _, s := range lines[1:] {
dev := strings.Split(s, "\t")
if len(dev) == 2 {
devices = append(devices, strings.TrimSpace(dev[0]))
}
}

return devices, nil
}

// Run a command to the given phone using exec
// Returns string and/or error
func (a *ADB) Exec(args ...string) ([]byte, error) {
if a.Serial == "" {
return exec.Command(a.ExePath, args...).Output()
} else {
var params []string
params = append(params, "-s", a.Serial)
params = append(params, args...)
return exec.Command(a.ExePath, params...).Output()
}
}

// GetState returns the output of `adb get-state`.
// It is used to check whether a device is connected. If it is not, adb
// will exit with status 1.
func (a *ADB) GetState() (string, error) {
log.Debug("Starting get-state")
out, err := exec.Command(a.ExePath, "get-state").Output()
out, err := a.Exec("get-state")
if err != nil {
log.Debug("get-state failed")
return "", err
Expand All @@ -53,7 +115,7 @@ func (a *ADB) GetState() (string, error) {
// Shell executes a shell command through adb.
func (a *ADB) Shell(cmd ...string) (string, error) {
fullCmd := append([]string{"shell"}, cmd...)
out, err := exec.Command(a.ExePath, fullCmd...).Output()
out, err := a.Exec(fullCmd...)
if err != nil {
if out == nil {
return "", err
Expand All @@ -67,7 +129,7 @@ func (a *ADB) Shell(cmd ...string) (string, error) {

// Pull downloads a file from the device to a local path.
func (a *ADB) Pull(remotePath, localPath string) (string, error) {
out, err := exec.Command(a.ExePath, "pull", remotePath, localPath).Output()
out, err := a.Exec("pull", remotePath, localPath)
if err != nil {
return string(out), err
}
Expand All @@ -77,7 +139,7 @@ func (a *ADB) Pull(remotePath, localPath string) (string, error) {

// Push a file on the phone
func (a *ADB) Push(localPath, remotePath string) (string, error) {
out, err := exec.Command(a.ExePath, "push", localPath, remotePath).Output()
out, err := a.Exec("push", localPath, remotePath)
if err != nil {
return string(out), err
}
Expand Down
13 changes: 8 additions & 5 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ func main() {
var list_modules bool
var fast bool
var module string
var output_folder string
var output_folder string
var serial string

// Command line options
flag.BoolVar(&verbose, "verbose", false, "Verbose mode")
Expand All @@ -55,8 +56,10 @@ func main() {
flag.BoolVar(&list_modules, "l", false, "List modules and exit")
flag.StringVar(&module, "module", "", "Only execute a specific module")
flag.StringVar(&module, "m", "", "Only execute a specific module")
flag.StringVar(&output_folder, "output", "", "Output folder")
flag.StringVar(&output_folder, "o", "", "Output folder")
flag.StringVar(&output_folder, "output", "", "Output folder")
flag.StringVar(&output_folder, "o", "", "Output folder")
flag.StringVar(&serial, "serial", "", "Phone serial number")
flag.StringVar(&serial, "s", "", "Phone serial number")
flag.BoolVar(&version_flag, "version", false, "Show version")

flag.Parse()
Expand All @@ -79,9 +82,9 @@ func main() {
}

log.Debug("Starting androidqf")
adb.Client, err = adb.New()
adb.Client, err = adb.New(serial)
if err != nil {
log.Fatal("Impossible to initialize adb")
log.Fatal("Impossible to initialize adb: ", err)
}

// Initialization
Expand Down

0 comments on commit b94438a

Please sign in to comment.