Implement adb forward

This commit is contained in:
timoxa0 2024-06-12 16:57:38 +05:00
parent 3f33e09453
commit 627bfc67be
2 changed files with 136 additions and 0 deletions

View file

@ -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 := fmt.Sprintf("killforward-all")
_, 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) ListForward() ([]Forward, error) {
req := fmt.Sprintf("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) {

63
adb/device_forward.go Normal file
View file

@ -0,0 +1,63 @@
package adb
import (
"strings"
"github.com/timoxa0/goadb/internal/errors"
)
type ForwardType uint8
const (
TypeInvalid ForwardType = iota
TCP
LOCAL
)
var forwardTypeStrings = map[string]ForwardType{
"tcp": TCP,
"local": LOCAL,
}
type ForwardTarget string
type ForwardLocal struct {
ftype ForwardType
target ForwardTarget
}
type ForwardRemote struct {
ftype ForwardType
target 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]],
target: ForwardTarget(raw_local[1]),
},
remote: ForwardRemote{
ftype: forwardTypeStrings[raw_remote[0]],
target: ForwardTarget(raw_remote[1]),
},
})
}
}
return forwards, errors.Errorf(errors.ParseError, "invalid device forward")
}