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. RunCommand runs the specified commands on a shell on the device.
From the Android docs: From the Android docs:
Run 'command arg1 arg2 ...' in a shell on the device, and return Run 'command arg1 arg2 ...' in a shell on the device, and return
its output and error streams. Note that arguments must be separated its output and error streams. Note that arguments must be separated
by spaces. If an argument contains a space, it must be quoted with 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. will go very wrong.
Note that this is the non-interactive version of "adb shell" Note that this is the non-interactive version of "adb shell"
Source: https://android.googlesource.com/platform/system/core/+/master/adb/SERVICES.TXT 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 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") 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: Remount, from the official adb commands docs:
Ask adbd to remount the device's filesystem in read-write mode, Ask adbd to remount the device's filesystem in read-write mode,
instead of read-only. This is usually necessary before performing instead of read-only. This is usually necessary before performing
an "adb sync" or "adb push" request. an "adb sync" or "adb push" request.
This request may not succeed on certain builds which do not allow This request may not succeed on certain builds which do not allow
that. that.
Source: https://android.googlesource.com/platform/system/core/+/master/adb/SERVICES.TXT Source: https://android.googlesource.com/platform/system/core/+/master/adb/SERVICES.TXT
*/ */
func (c *Device) Remount() (string, error) { 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")
}