2016-01-15 15:54:27 +00:00
|
|
|
|
package adb
|
2015-04-11 21:45:29 +00:00
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"strconv"
|
|
|
|
|
|
2020-10-29 02:18:51 +00:00
|
|
|
|
"github.com/evrins/goadb/internal/errors"
|
|
|
|
|
"github.com/evrins/goadb/wire"
|
2015-04-11 21:45:29 +00:00
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
/*
|
2016-05-22 05:33:20 +00:00
|
|
|
|
Adb communicates with host services on the adb server.
|
2015-04-11 21:45:29 +00:00
|
|
|
|
|
|
|
|
|
Eg.
|
2020-07-13 06:18:10 +00:00
|
|
|
|
client := New()
|
2015-04-12 20:34:20 +00:00
|
|
|
|
client.ListDevices()
|
2015-04-11 21:45:29 +00:00
|
|
|
|
|
|
|
|
|
See list of services at https://android.googlesource.com/platform/system/core/+/master/adb/SERVICES.TXT.
|
|
|
|
|
*/
|
2015-04-12 20:34:20 +00:00
|
|
|
|
// TODO(z): Finish implementing host services.
|
2016-05-22 05:33:20 +00:00
|
|
|
|
type Adb struct {
|
|
|
|
|
server server
|
2015-04-12 20:34:20 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-05-22 05:33:20 +00:00
|
|
|
|
// New creates a new Adb client that uses the default ServerConfig.
|
|
|
|
|
func New() (*Adb, error) {
|
|
|
|
|
return NewWithConfig(ServerConfig{})
|
2015-04-11 21:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2016-05-22 05:33:20 +00:00
|
|
|
|
func NewWithConfig(config ServerConfig) (*Adb, error) {
|
|
|
|
|
server, err := newServer(config)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return &Adb{server}, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Dial establishes a connection with the adb server.
|
|
|
|
|
func (c *Adb) Dial() (*wire.Conn, error) {
|
|
|
|
|
return c.server.Dial()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Starts the adb server if it’s not running.
|
|
|
|
|
func (c *Adb) StartServer() error {
|
|
|
|
|
return c.server.Start()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Adb) Device(descriptor DeviceDescriptor) *Device {
|
|
|
|
|
return &Device{
|
|
|
|
|
server: c.server,
|
|
|
|
|
descriptor: descriptor,
|
|
|
|
|
deviceListFunc: c.ListDevices,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *Adb) NewDeviceWatcher() *DeviceWatcher {
|
|
|
|
|
return newDeviceWatcher(c.server)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ServerVersion asks the ADB server for its internal version number.
|
|
|
|
|
func (c *Adb) ServerVersion() (int, error) {
|
2016-01-10 21:33:22 +00:00
|
|
|
|
resp, err := roundTripSingleResponse(c.server, "host:version")
|
2015-04-11 21:45:29 +00:00
|
|
|
|
if err != nil {
|
2015-07-12 06:18:58 +00:00
|
|
|
|
return 0, wrapClientError(err, c, "GetServerVersion")
|
2015-04-11 21:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
2015-07-12 06:18:58 +00:00
|
|
|
|
version, err := c.parseServerVersion(resp)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, wrapClientError(err, c, "GetServerVersion")
|
|
|
|
|
}
|
|
|
|
|
return version, nil
|
2015-04-11 21:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
KillServer tells the server to quit immediately.
|
|
|
|
|
|
|
|
|
|
Corresponds to the command:
|
|
|
|
|
adb kill-server
|
|
|
|
|
*/
|
2016-05-22 05:33:20 +00:00
|
|
|
|
func (c *Adb) KillServer() error {
|
2016-01-10 21:33:22 +00:00
|
|
|
|
conn, err := c.server.Dial()
|
2015-04-11 21:45:29 +00:00
|
|
|
|
if err != nil {
|
2015-07-12 06:18:58 +00:00
|
|
|
|
return wrapClientError(err, c, "KillServer")
|
2015-04-11 21:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
defer conn.Close()
|
|
|
|
|
|
2015-04-12 20:34:20 +00:00
|
|
|
|
if err = wire.SendMessageString(conn, "host:kill"); err != nil {
|
2015-07-12 06:18:58 +00:00
|
|
|
|
return wrapClientError(err, c, "KillServer")
|
2015-04-11 21:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
ListDeviceSerials returns the serial numbers of all attached devices.
|
|
|
|
|
|
|
|
|
|
Corresponds to the command:
|
|
|
|
|
adb devices
|
|
|
|
|
*/
|
2016-05-22 05:33:20 +00:00
|
|
|
|
func (c *Adb) ListDeviceSerials() ([]string, error) {
|
2016-01-10 21:33:22 +00:00
|
|
|
|
resp, err := roundTripSingleResponse(c.server, "host:devices")
|
2015-04-11 21:45:29 +00:00
|
|
|
|
if err != nil {
|
2015-07-12 06:18:58 +00:00
|
|
|
|
return nil, wrapClientError(err, c, "ListDeviceSerials")
|
2015-04-11 21:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
devices, err := parseDeviceList(string(resp), parseDeviceShort)
|
|
|
|
|
if err != nil {
|
2015-07-12 06:18:58 +00:00
|
|
|
|
return nil, wrapClientError(err, c, "ListDeviceSerials")
|
2015-04-11 21:45:29 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
serials := make([]string, len(devices))
|
|
|
|
|
for i, dev := range devices {
|
|
|
|
|
serials[i] = dev.Serial
|
|
|
|
|
}
|
|
|
|
|
return serials, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
ListDevices returns the list of connected devices.
|
|
|
|
|
|
|
|
|
|
Corresponds to the command:
|
|
|
|
|
adb devices -l
|
|
|
|
|
*/
|
2016-05-22 05:33:20 +00:00
|
|
|
|
func (c *Adb) ListDevices() ([]*DeviceInfo, error) {
|
2016-01-10 21:33:22 +00:00
|
|
|
|
resp, err := roundTripSingleResponse(c.server, "host:devices-l")
|
2015-04-11 21:45:29 +00:00
|
|
|
|
if err != nil {
|
2015-07-12 06:18:58 +00:00
|
|
|
|
return nil, wrapClientError(err, c, "ListDevices")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
devices, err := parseDeviceList(string(resp), parseDeviceLong)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, wrapClientError(err, c, "ListDevices")
|
2015-04-11 21:45:29 +00:00
|
|
|
|
}
|
2015-07-12 06:18:58 +00:00
|
|
|
|
return devices, nil
|
|
|
|
|
}
|
2015-04-11 21:45:29 +00:00
|
|
|
|
|
2016-05-22 05:33:20 +00:00
|
|
|
|
func (c *Adb) parseServerVersion(versionRaw []byte) (int, error) {
|
2015-07-12 06:18:58 +00:00
|
|
|
|
versionStr := string(versionRaw)
|
|
|
|
|
version, err := strconv.ParseInt(versionStr, 16, 32)
|
|
|
|
|
if err != nil {
|
2016-05-22 17:49:32 +00:00
|
|
|
|
return 0, errors.WrapErrorf(err, errors.ParseError,
|
2015-07-12 06:18:58 +00:00
|
|
|
|
"error parsing server version: %s", versionStr)
|
|
|
|
|
}
|
|
|
|
|
return int(version), nil
|
2015-04-11 21:45:29 +00:00
|
|
|
|
}
|