mirror of
https://github.com/taigrr/adb.git
synced 2026-04-14 08:18:23 -07:00
Compare commits
3 Commits
cd/tests-q
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 1cb8e59d0d | |||
| 747c4abb7f | |||
| 80d01ae3e9 |
28
README.md
28
README.md
@@ -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 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.
|
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.
|
`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..., please [Submit a Pull Request](https://github.com/taigrr/adb/pulls).
|
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
|
## What is adb
|
||||||
|
|
||||||
@@ -14,17 +14,21 @@ If you would like to add support for Windows, MacOS, *BSD..., please [Submit a P
|
|||||||
|
|
||||||
## Supported adb functions
|
## Supported adb functions
|
||||||
|
|
||||||
- [ ] `adb connect`
|
- [x] `adb connect`
|
||||||
- [ ] `adb disconnect`
|
- [x] `adb disconnect`
|
||||||
- [ ] `adb shell <input>s`
|
- [x] `adb shell <command>`
|
||||||
- [ ] `adb kill-server`
|
- [x] `adb kill-server`
|
||||||
- [ ] `adb device`
|
- [x] `adb devices`
|
||||||
- [ ] `adb pull`
|
- [x] `adb pull`
|
||||||
- [ ] `adb install`
|
- [ ] `adb install`
|
||||||
- [ ] `adb push`
|
- [x] `adb push`
|
||||||
- [ ] `adb reboot`
|
- [x] `adb reboot`
|
||||||
- [ ] `adb shell input tap X Y`
|
- [x] `adb root`
|
||||||
- [ ] `adb shell input swipe X1 Y1 X2 Y2 duration`
|
- [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,
|
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)
|
Feel free to [Open an Issue](https://github.com/taigrr/adb/issues) or [Submit a Pull Request](https://github.com/taigrr/adb/pulls)
|
||||||
|
|||||||
7
adb.go
7
adb.go
@@ -51,10 +51,11 @@ func Connect(ctx context.Context, opts ConnOptions) (Device, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d Device) ConnString() string {
|
func (d Device) ConnString() string {
|
||||||
if d.Port == 0 {
|
port := d.Port
|
||||||
d.Port = 5555
|
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.
|
// Connect to a previously discovered device.
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"log"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -236,10 +235,7 @@ func (d Device) CaptureSequence(ctx context.Context) (t TapSequence, err error)
|
|||||||
if errors.Is(err, ErrUnspecified) {
|
if errors.Is(err, ErrUnspecified) {
|
||||||
err = nil
|
err = nil
|
||||||
}
|
}
|
||||||
if errCode != 130 && errCode != -1 && errCode != 1 {
|
_ = errCode
|
||||||
// TODO remove log output here
|
|
||||||
log.Printf("Expected error code 130 or -1, but got %d\n", errCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
if stdout == "" {
|
if stdout == "" {
|
||||||
return TapSequence{}, ErrStdoutEmpty
|
return TapSequence{}, ErrStdoutEmpty
|
||||||
|
|||||||
10
errors.go
10
errors.go
@@ -17,6 +17,16 @@ var (
|
|||||||
ErrResolutionParseFail = errors.New("failed to parse screen size from input text")
|
ErrResolutionParseFail = errors.New("failed to parse screen size from input text")
|
||||||
// ErrDestExists is returned when a pull destination file already exists.
|
// ErrDestExists is returned when a pull destination file already exists.
|
||||||
ErrDestExists = errors.New("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 is returned when the exact error cannot be determined.
|
||||||
ErrUnspecified = errors.New("an unknown error has occurred, please open an issue on GitHub")
|
ErrUnspecified = errors.New("an unknown error has occurred, please open an issue on GitHub")
|
||||||
)
|
)
|
||||||
|
|||||||
2
go.mod
2
go.mod
@@ -1,5 +1,5 @@
|
|||||||
module github.com/taigrr/adb
|
module github.com/taigrr/adb
|
||||||
|
|
||||||
go 1.26.1
|
go 1.26.2
|
||||||
|
|
||||||
require github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
require github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510
|
||||||
|
|||||||
20
util.go
20
util.go
@@ -5,6 +5,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -56,7 +57,22 @@ func execute(ctx context.Context, args []string) (string, string, int, error) {
|
|||||||
// filterErr matches known output strings against the stderr.
|
// filterErr matches known output strings against the stderr.
|
||||||
//
|
//
|
||||||
// The inferred error type is then returned.
|
// The inferred error type is then returned.
|
||||||
// TODO: implement
|
|
||||||
func filterErr(stderr string) error {
|
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
util_test.go
14
util_test.go
@@ -1,6 +1,7 @@
|
|||||||
package adb
|
package adb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -8,15 +9,20 @@ func Test_filterErr(t *testing.T) {
|
|||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
stderr string
|
stderr string
|
||||||
wantErr bool
|
wantErr error
|
||||||
}{
|
}{
|
||||||
{name: "empty stderr", stderr: "", wantErr: false},
|
{name: "empty stderr", stderr: "", wantErr: nil},
|
||||||
{name: "random output", stderr: "some warning text", wantErr: false},
|
{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 {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
err := filterErr(tt.stderr)
|
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)
|
t.Errorf("filterErr() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user