Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
This library aims at providing idiomatic `adb` bindings for go developers, in order to make it easier to write system tooling using golang.
This tool tries to take guesswork out of arbitrarily shelling out to `adb` by providing a structured, thoroughly-tested wrapper for the `adb` functions most-likely to be used in a system program.

If `adb` must be installed in your path `PATH`. At this time, while this library may work on Windows or MacOS, only Linux is supported.
If you would like to add support for Windows, MacOS, *BSD..., please [Submit a Pull Request](https://github.com/taigrr/adb/pulls).
`adb` must be installed and available in your `PATH`. At this time, while this library may work on Windows or macOS, only Linux is supported.
If you would like to add support for Windows, macOS, *BSD, etc., please [Submit a Pull Request](https://github.com/taigrr/adb/pulls).

## What is adb

Expand All @@ -14,17 +14,21 @@ If you would like to add support for Windows, MacOS, *BSD..., please [Submit a P

## Supported adb functions

- [ ] `adb connect`
- [ ] `adb disconnect`
- [ ] `adb shell <input>s`
- [ ] `adb kill-server`
- [ ] `adb device`
- [ ] `adb pull`
- [x] `adb connect`
- [x] `adb disconnect`
- [x] `adb shell <command>`
- [x] `adb kill-server`
- [x] `adb devices`
- [x] `adb pull`
- [ ] `adb install`
- [ ] `adb push`
- [ ] `adb reboot`
- [ ] `adb shell input tap X Y`
- [ ] `adb shell input swipe X1 Y1 X2 Y2 duration`
- [x] `adb push`
- [x] `adb reboot`
- [x] `adb root`
- [x] `adb shell input tap X Y`
- [x] `adb shell input swipe X1 Y1 X2 Y2 duration`
- [x] `adb shell input keyevent` (home, back, app switch)
- [x] `adb shell wm size` (screen resolution)
- [x] `adb shell getevent` (capture and replay tap sequences)

Please note that as this is a purpose-driven project library, not all functionality of ADB is currently supported, but if you need functionality that's not currently supported,
Feel free to [Open an Issue](https://github.com/taigrr/adb/issues) or [Submit a Pull Request](https://github.com/taigrr/adb/pulls)
Expand Down
7 changes: 4 additions & 3 deletions adb.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ func Connect(ctx context.Context, opts ConnOptions) (Device, error) {
}

func (d Device) ConnString() string {
if d.Port == 0 {
d.Port = 5555
port := d.Port
if port == 0 {
port = 5555
}
return d.IP.String() + ":" + strconv.Itoa(int(d.Port))
return d.IP.String() + ":" + strconv.Itoa(int(port))
}

// Connect to a previously discovered device.
Expand Down
6 changes: 1 addition & 5 deletions capture.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"encoding/json"
"errors"
"log"
"regexp"
"strconv"
"strings"
Expand Down Expand Up @@ -236,10 +235,7 @@ func (d Device) CaptureSequence(ctx context.Context) (t TapSequence, err error)
if errors.Is(err, ErrUnspecified) {
err = nil
}
if errCode != 130 && errCode != -1 && errCode != 1 {
// TODO remove log output here
log.Printf("Expected error code 130 or -1, but got %d\n", errCode)
}
_ = errCode

if stdout == "" {
return TapSequence{}, ErrStdoutEmpty
Expand Down
10 changes: 10 additions & 0 deletions errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ var (
ErrResolutionParseFail = errors.New("failed to parse screen size from input text")
// ErrDestExists is returned when a pull destination file already exists.
ErrDestExists = errors.New("destination file already exists")
// ErrDeviceNotFound is returned when no device is connected or the target device cannot be found.
ErrDeviceNotFound = errors.New("device not found")
// ErrDeviceOffline is returned when the target device is offline.
ErrDeviceOffline = errors.New("device offline")
// ErrDeviceUnauthorized is returned when the device has not authorized USB debugging.
ErrDeviceUnauthorized = errors.New("device unauthorized; check the confirmation dialog on the device")
// ErrConnectionRefused is returned when the connection to a device is refused.
ErrConnectionRefused = errors.New("connection refused")
// ErrMoreThanOneDevice is returned when multiple devices are connected and no serial is specified.
ErrMoreThanOneDevice = errors.New("more than one device/emulator; use -s to specify a device")
// ErrUnspecified is returned when the exact error cannot be determined.
ErrUnspecified = errors.New("an unknown error has occurred, please open an issue on GitHub")
)
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
module github.com/taigrr/adb

go 1.26.1
go 1.26.2

require github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
20 changes: 18 additions & 2 deletions util.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"fmt"
"os/exec"
"strings"
"sync"
)

Expand Down Expand Up @@ -56,7 +57,22 @@ func execute(ctx context.Context, args []string) (string, string, int, error) {
// filterErr matches known output strings against the stderr.
//
// The inferred error type is then returned.
// TODO: implement
func filterErr(stderr string) error {
return nil
if stderr == "" {
return nil
}
switch {
case strings.Contains(stderr, "device not found"):
return ErrDeviceNotFound
case strings.Contains(stderr, "device offline"):
return ErrDeviceOffline
case strings.Contains(stderr, "device unauthorized"):
return ErrDeviceUnauthorized
case strings.Contains(stderr, "Connection refused"):
return ErrConnectionRefused
case strings.Contains(stderr, "more than one device"):
return ErrMoreThanOneDevice
default:
return nil
}
}
14 changes: 10 additions & 4 deletions util_test.go
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
package adb

import (
"errors"
"testing"
)

func Test_filterErr(t *testing.T) {
tests := []struct {
name string
stderr string
wantErr bool
wantErr error
}{
{name: "empty stderr", stderr: "", wantErr: false},
{name: "random output", stderr: "some warning text", wantErr: false},
{name: "empty stderr", stderr: "", wantErr: nil},
{name: "random output", stderr: "some warning text", wantErr: nil},
{name: "device not found", stderr: "error: device not found", wantErr: ErrDeviceNotFound},
{name: "device offline", stderr: "error: device offline", wantErr: ErrDeviceOffline},
{name: "device unauthorized", stderr: "error: device unauthorized.\nThis adb server's $ADB_VENDOR_KEYS is not set", wantErr: ErrDeviceUnauthorized},
{name: "connection refused", stderr: "cannot connect to daemon at tcp:5037: Connection refused", wantErr: ErrConnectionRefused},
{name: "more than one device", stderr: "error: more than one device/emulator", wantErr: ErrMoreThanOneDevice},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := filterErr(tt.stderr)
if (err != nil) != tt.wantErr {
if !errors.Is(err, tt.wantErr) {
t.Errorf("filterErr() error = %v, wantErr %v", err, tt.wantErr)
}
})
Expand Down
Loading