Compare commits

...

10 commits

38 changed files with 206 additions and 56 deletions

View file

@ -1,7 +1,5 @@
#goadb
[![Build Status](https://travis-ci.org/zach-klippenstein/goadb.svg?branch=master)](https://travis-ci.org/zach-klippenstein/goadb)
[![GoDoc](https://godoc.org/goadb?status.svg)](https://godoc.org/goadb)
[![GoDoc](https://pkg.go.dev/github.com/timoxa0/goadb?status.svg)](https://pkg.go.dev/github.com/timoxa0/goadb)
A Golang library for interacting with the Android Debug Bridge (adb).

View file

@ -3,8 +3,8 @@ package adb
import (
"strconv"
"github.com/evrins/goadb/internal/errors"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/internal/errors"
"github.com/timoxa0/goadb/wire"
)
/*

View file

@ -3,7 +3,7 @@ package adb
import (
"testing"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/wire"
"github.com/stretchr/testify/assert"
)

View file

@ -7,8 +7,8 @@ import (
"strings"
"time"
"github.com/evrins/goadb/internal/errors"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/internal/errors"
"github.com/timoxa0/goadb/wire"
)
// MtimeOfClose should be passed to OpenWrite to set the file modification time to the time the Close
@ -80,6 +80,7 @@ func (c *Device) DeviceInfo() (*DeviceInfo, error) {
RunCommand runs the specified commands on a shell on the device.
From the Android docs:
Run 'command arg1 arg2 ...' in a shell on the device, and return
its output and error streams. Note that arguments must be separated
by spaces. If an argument contains a space, it must be quoted with
@ -87,6 +88,7 @@ From the Android docs:
will go very wrong.
Note that this is the non-interactive version of "adb shell"
Source: https://android.googlesource.com/platform/system/core/+/master/adb/SERVICES.TXT
This method quotes the arguments for you, and will return an error if any of them
@ -120,13 +122,84 @@ func (c *Device) RunCommand(cmd string, args ...string) (string, error) {
return string(resp), wrapClientError(err, c, "RunCommand")
}
/*
Forward, from the official adb command's docs:
Asks the ADB server to forward local connections from <local>
to the <remote> address on a given device.
There, <host-prefix> can be one of the
host-serial/host-usb/host-local/host prefixes as described previously
and indicates which device/emulator to target.
the format of <local> is one of:
tcp:<port> -> TCP connection on localhost:<port>
local:<path> -> Unix local domain socket on <path>
the format of <remote> is one of:
tcp:<port> -> TCP localhost:<port> on device
local:<path> -> Unix local domain socket on device
jdwp:<pid> -> JDWP thread on VM process <pid>
vsock:<CID>:<port> -> vsock on the given CID and port
or even any one of the local services described below.
Source: https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/SERVICES.TXT
*/
func (c *Device) Forward(local string, remote string) error {
req := fmt.Sprintf("forward:%s;%s", local, remote)
_, err := c.getAttribute(req)
return wrapClientError(err, c, "Forward")
}
/*
KillForward, from the official adb command's docs:
Remove any existing forward local connection from <local>.
Source: https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/SERVICES.TXT
*/
func (c *Device) KillForward(local string) error {
req := fmt.Sprintf("killforward:%s", local)
_, err := c.getAttribute(req)
return wrapClientError(err, c, "KillForward")
}
/*
KillForwardAll, from the official adb command's docs:
Remove all forward network connections.
Source: https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/SERVICES.TXT
*/
func (c *Device) KillForwardAll() error {
req := "killforward-all"
_, err := c.getAttribute(req)
return wrapClientError(err, c, "KillForward")
}
/*
ListForwards, from the official adb command's docs:
List all existing forward connections from this server.
Source: https://android.googlesource.com/platform/packages/modules/adb/+/refs/heads/main/SERVICES.TXT
*/
func (c *Device) ListForwards() ([]Forward, error) {
req := "list-forward"
resp, err := c.getAttribute(req)
if err != nil {
return nil, wrapClientError(err, c, "ListForwards")
}
forwards, err := parseForward(resp, c.descriptor.serial)
return forwards, wrapClientError(err, c, "ListForwards")
}
/*
Remount, from the official adb commands docs:
Ask adbd to remount the device's filesystem in read-write mode,
instead of read-only. This is usually necessary before performing
an "adb sync" or "adb push" request.
This request may not succeed on certain builds which do not allow
that.
Source: https://android.googlesource.com/platform/system/core/+/master/adb/SERVICES.TXT
*/
func (c *Device) Remount() (string, error) {

61
adb/device_forward.go Normal file
View file

@ -0,0 +1,61 @@
package adb
import (
"strings"
)
type ForwardType int8
const (
TypeInvalid ForwardType = iota
ForwardTCP
ForwardLOCAL
)
var forwardTypeStrings = map[string]ForwardType{
"tcp": ForwardTCP,
"local": ForwardLOCAL,
}
type ForwardTarget string
type ForwardLocal struct {
FType ForwardType
FTarget ForwardTarget
}
type ForwardRemote struct {
FType ForwardType
FTarget ForwardTarget
}
type Forward struct {
Local ForwardLocal
Remote ForwardRemote
}
func parseForward(str string, deviceSerial string) ([]Forward, error) {
var forwards []Forward
for _, forwardStr := range strings.Split(str, "\n") {
if strings.Trim(forwardStr, "\n\t ") == "" {
continue
}
raw_forward := strings.Split(forwardStr, " ")
serial, local, remote := raw_forward[0], raw_forward[1], raw_forward[2]
if serial == deviceSerial {
raw_local := strings.Split(local, ":")
raw_remote := strings.Split(remote, ":")
forwards = append(forwards, Forward{
Local: ForwardLocal{
FType: forwardTypeStrings[raw_local[0]],
FTarget: ForwardTarget(raw_local[1]),
},
Remote: ForwardRemote{
FType: forwardTypeStrings[raw_remote[0]],
FTarget: ForwardTarget(raw_remote[1]),
},
})
}
}
return forwards, nil
}

View file

@ -4,7 +4,7 @@ import (
"bufio"
"strings"
"github.com/evrins/goadb/internal/errors"
"github.com/timoxa0/goadb/internal/errors"
)
type DeviceInfo struct {
@ -87,5 +87,8 @@ func parseDeviceAttributes(fields []string) map[string]string {
// Parses a key:val pair and returns key, val.
func parseKeyVal(pair string) (string, string) {
split := strings.Split(pair, ":")
if len(split) == 1 {
return split[0], ""
}
return split[0], split[1]
}

View file

@ -1,15 +1,14 @@
package adb
import (
"github.com/evrins/goadb/internal/errors"
)
import "github.com/timoxa0/goadb/internal/errors"
// DeviceState represents one of the 3 possible states adb will report devices.
// A device can be communicated with when it's in StateOnline.
// A USB device will make the following state transitions:
//
// Plugged in: StateDisconnected->StateOffline->StateOnline
// Unplugged: StateOnline->StateDisconnected
// Plugged in: StateDisconnected->StateOffline->StateOnline
// Plugged in (Recoveory): StateDisconnected->StateOnline
// Unplugged: StateOnline->StateDisconnected
//
//go:generate stringer -type=DeviceState
type DeviceState int8

View file

@ -3,8 +3,8 @@ package adb
import (
"testing"
"github.com/evrins/goadb/internal/errors"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/internal/errors"
"github.com/timoxa0/goadb/wire"
"github.com/stretchr/testify/assert"
)

View file

@ -8,8 +8,8 @@ import (
"sync/atomic"
"time"
"github.com/evrins/goadb/internal/errors"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/internal/errors"
"github.com/timoxa0/goadb/wire"
)
/*

View file

@ -3,8 +3,8 @@ package adb
import (
"testing"
"github.com/evrins/goadb/internal/errors"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/internal/errors"
"github.com/timoxa0/goadb/wire"
"github.com/stretchr/testify/assert"
)

View file

@ -5,8 +5,8 @@ import (
"net"
"runtime"
"github.com/evrins/goadb/internal/errors"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/internal/errors"
"github.com/timoxa0/goadb/wire"
)
// Dialer knows how to create connections to an adb server.

View file

@ -5,7 +5,7 @@ import (
"os"
"time"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/wire"
)
// DirEntry holds information about a directory entry on a device.

View file

@ -1,6 +1,6 @@
package adb
import "github.com/evrins/goadb/internal/errors"
import "github.com/timoxa0/goadb/internal/errors"
type ErrCode errors.ErrCode

16
adb/forward_string.go Normal file
View file

@ -0,0 +1,16 @@
// Code generated by "stringer -type=ForwardType"; DO NOT EDIT
package adb
import "fmt"
const _ForwardType_name = "InvalidTCPLocal"
var _ForwardType_index = [...]uint8{0, 7, 10, 15}
func (i ForwardType) String() string {
if i < 0 || i >= ForwardType(len(_ForwardType_index)-1) {
return fmt.Sprintf("ForwardType(%d)", i)
}
return _ForwardType_name[_ForwardType_index[i]:_ForwardType_index[i+1]]
}

View file

@ -7,8 +7,8 @@ import (
"os/exec"
"strings"
"github.com/evrins/goadb/internal/errors"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/internal/errors"
"github.com/timoxa0/goadb/wire"
)
const (

View file

@ -4,8 +4,8 @@ import (
"io"
"strings"
"github.com/evrins/goadb/internal/errors"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/internal/errors"
"github.com/timoxa0/goadb/wire"
)
// MockServer implements Server, Scanner, and Sender.

View file

@ -4,7 +4,7 @@ import (
"fmt"
"testing"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/wire"
"github.com/stretchr/testify/assert"
)

View file

@ -5,8 +5,8 @@ import (
"os"
"time"
"github.com/evrins/goadb/internal/errors"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/internal/errors"
"github.com/timoxa0/goadb/wire"
)
var zeroTime = time.Unix(0, 0).UTC()

View file

@ -7,8 +7,8 @@ import (
"testing"
"time"
"github.com/evrins/goadb/internal/errors"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/internal/errors"
"github.com/timoxa0/goadb/wire"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

View file

@ -3,8 +3,8 @@ package adb
import (
"io"
"github.com/evrins/goadb/internal/errors"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/internal/errors"
"github.com/timoxa0/goadb/wire"
)
// syncFileReader wraps a SyncConn that has requested to receive a file.

View file

@ -6,7 +6,7 @@ import (
"strings"
"testing"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/wire"
"github.com/stretchr/testify/assert"
)

View file

@ -6,8 +6,8 @@ import (
"os"
"time"
"github.com/evrins/goadb/internal/errors"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/internal/errors"
"github.com/timoxa0/goadb/wire"
)
// syncFileWriter wraps a SyncConn that has requested to send a file.

View file

@ -8,7 +8,7 @@ import (
"encoding/binary"
"strings"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/wire"
"github.com/stretchr/testify/assert"
)

View file

@ -6,7 +6,7 @@ import (
"regexp"
"strings"
"github.com/evrins/goadb/internal/errors"
"github.com/timoxa0/goadb/internal/errors"
)
var (

View file

@ -2,7 +2,7 @@ package main
import (
"fmt"
"github.com/evrins/goadb/adb"
"github.com/timoxa0/goadb/adb"
"io"
"os"
"path/filepath"

View file

@ -4,12 +4,12 @@ package main
import (
"flag"
"fmt"
"github.com/evrins/goadb/adb"
"github.com/timoxa0/goadb/adb"
"io/ioutil"
"log"
"time"
"github.com/evrins/goadb/internal/errors"
"github.com/timoxa0/goadb/internal/errors"
)
var (

View file

@ -5,13 +5,13 @@ import (
"bufio"
"flag"
"fmt"
"github.com/evrins/goadb/adb"
"github.com/timoxa0/goadb/adb"
"io"
"log"
"os"
"strings"
"github.com/evrins/goadb/wire"
"github.com/timoxa0/goadb/wire"
)
var port = flag.Int("p", adb.AdbPort, "`port` the adb server is listening on")

2
go.mod
View file

@ -1,4 +1,4 @@
module github.com/evrins/goadb
module github.com/timoxa0/goadb
go 1.14

View file

@ -1,6 +1,6 @@
package wire
import "github.com/evrins/goadb/internal/errors"
import "github.com/timoxa0/goadb/internal/errors"
const (
// The official implementation of adb imposes an undocumented 255-byte limit

View file

@ -6,7 +6,7 @@ import (
"io/ioutil"
"strconv"
"github.com/evrins/goadb/internal/errors"
"github.com/timoxa0/goadb/internal/errors"
)
// TODO(zach): All EOF errors returned from networoking calls should use ConnectionResetError.

View file

@ -7,7 +7,7 @@ import (
"io/ioutil"
"testing"
"github.com/evrins/goadb/internal/errors"
"github.com/timoxa0/goadb/internal/errors"
"github.com/stretchr/testify/assert"
)

View file

@ -4,7 +4,7 @@ import (
"fmt"
"io"
"github.com/evrins/goadb/internal/errors"
"github.com/timoxa0/goadb/internal/errors"
)
// Sender sends messages to the server.

View file

@ -1,6 +1,6 @@
package wire
import "github.com/evrins/goadb/internal/errors"
import "github.com/timoxa0/goadb/internal/errors"
const (
// Chunks cannot be longer than 64k.

View file

@ -6,7 +6,7 @@ import (
"os"
"time"
"github.com/evrins/goadb/internal/errors"
"github.com/timoxa0/goadb/internal/errors"
)
type SyncScanner interface {

View file

@ -6,7 +6,7 @@ import (
"os"
"time"
"github.com/evrins/goadb/internal/errors"
"github.com/timoxa0/goadb/internal/errors"
)
type SyncSender interface {

View file

@ -7,7 +7,7 @@ import (
"testing"
"time"
"github.com/evrins/goadb/internal/errors"
"github.com/timoxa0/goadb/internal/errors"
"github.com/stretchr/testify/assert"
)

View file

@ -6,7 +6,7 @@ import (
"regexp"
"sync"
"github.com/evrins/goadb/internal/errors"
"github.com/timoxa0/goadb/internal/errors"
)
// ErrorResponseDetails is an error message returned by the server for a particular request.

View file

@ -3,7 +3,7 @@ package wire
import (
"testing"
"github.com/evrins/goadb/internal/errors"
"github.com/timoxa0/goadb/internal/errors"
"github.com/stretchr/testify/assert"
)