adb

package module
v0.1.0-devel Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 8, 2019 License: Apache-2.0 Imports: 14 Imported by: 0

README

A Golang library for interacting with the Android Debug Bridge (adb).

A note from the fork's autor:

This is a side project of mine. Do not expect any support or replies to feature or bug request.

The reason for this fork was that I wasn't happy with the internals. There were simply too many types and it seemd overcomplex.

If you are looking for a propper adb client library in Go, take a look a the implementation provided by Google.

DONE (mostly):

Asyncwriter rewritten

  • now counts based on bytes written
  • does not filestat (racy?) removed useage of runtime.SetFinalizer
  • this is considered bad style
  • better use Close properly flatten
  • remove unessecarry types
  • remove top-level sybols
  • inline functions
  • do things in-place (tetra to le int)
  • get rid of dependencies (rhttp!?)
  • simplify names simplified error handling (maybe readd some)
  • why internal package?
  • no buissness in this
  • now uses pkg/errors removed useage of return parameters moved away from []byte/strings to io.Reader
  • use more io.Copy, io.ReaderTo, io.WriterFrom removed adb/wire
  • abstraction was broken anyways
  • don't export interfaces
  • moved to net.Conn and io.Reader/Writer 'log' useage of device watcher removed (moved to fmt.Printf, missing timestamp) reimplement command handling
  • what about echo :$? (this is actually fine)
  • look into documentation for a better way to get exit status rework how device descriptor work and how device connects to the server
  • always use serial as query-prefix `host-serial: &lt serial-number &gt : request
  • better track connection state (when reuse, when drop) socket read/writes
  • only use two reads per message, header and body
  • only allocate once
  • use io.ReadFull
  • investigate if write full neccessary
  • reduce allocations for message sends change ForwartSpec to a simple string implement os.FileInfo for dir_entries move cmd/demo and cmd/raw-adb to example files implement formatter for deviceInfo think about features of device_extra (what to keep/remove?)

TODO:

write more tests (table driven style) track (potential) leakages expose low-level adb interface

Notice About hierarchy flattening: See: https://github.com/golang/go/wiki/CodeReviewComments#interfaces

Device (new)

  • Server
    • path
    • address
  • serial

Device (old)

  • sever (interface)
    • realServer
      • ServerConfig
        • PathToADB
        • Host
        • Port
        • Dialer (interface)
          • tcpDialer
          • wire.Conn
            • Scanner (interface)
              • realScanner
                • SyncScanner (interface)
                  • realSyncScanner
                  • StatusReader
              • StatusReader
            • Sender (interface)
              • realSender
              • SyncSender (interface)
                • realSyncSender
        • filesystem
      • address
  • DeviceDescriptor
    • deviceDescriptorType
    • serial
  • deviceListFunc

Status

Host:

  • version [x]
  • kill [x]
  • devices(-l) [x]
  • track-devices [ ] needs investigation

Device:

  • get-devpath [x]
  • get-state; check this beforehand, poll?
  • Forward:
    • foreward
    • norebind
    • killforward
    • list-forward
  • shell [x]
  • remount [ ] result type need investigation, use this before sync/push
  • dev [x]
  • tcp?
  • local?
  • framebuffer?
  • jdwp?
  • reverse?

Sync:

  • List [x]
  • Send [ ] change abstraction to accepting reader
  • Retrieve [x]
  • Stat [x]

Other:

  • host: emulator; don't implement this, not for clients
  • device: product N/A
  • device: get-serialno; uneccessary as this is the device ID

Documentation

Overview

Package adb is a Go package for interoperation with the Android Debug Bridge (adb).

The client/server spec is defined at https://android.googlesource.com/platform/system/core/+/master/adb/OVERVIEW.TXT.

WARNING This library is under heavy development, and its API is likely to change without notice. Use versioning!

See README for more information. Use `go doc` or godoc.org for documentation.

Example
package main

import (
	"fmt"
	"time"

	"github.com/d1ced/adb"
)

func main() {

	client, _ := adb.NewDefault()

	serverVersion, _ := client.Version()
	fmt.Println("Server version:", serverVersion)

	deviceInfo, _ := client.ListDevices()

	fmt.Println("Devices:")
	for _, device := range deviceInfo {
		fmt.Println(device)
	}

	fmt.Println("Watching for device state changes.")
	watcher, err := client.NewDeviceWatcher()
	if err != nil {
		panic(err)
	}

	go func() {
		<-time.After(20 * time.Second)
		watcher.Close()
	}()

	for event := range watcher.C() {
		fmt.Printf("\t[%s]%+v\n", time.Now(), event)
	}
	if err = watcher.Err(); err != nil {
		fmt.Println(err)
	}

	client.Kill()
}
Output:

Index

Examples

Constants

View Source
const (
	FProtocolTCP   = "tcp"
	FProtocolLocal = "local"
	FProtocolJDWP  = "jdwp"

	// TODO(jmh): check if they are still in use.
	FProtocolAbstract   = "localabstract"
	FProtocolReserved   = "localreserved"
	FProtocolFilesystem = "localfilesystem"
)

ForwardSpec protocols

View Source
const (
	// DefaultExecutableName is the name of the ADB-Server on the Path
	DefaultExecutableName = "adb"
	// DefaultPort is the default port for the ADB-Server to listens on.
	DefaultPort = 5037
)

Variables

View Source
var (
	// The connection to the server was reset in the middle of an operation. Server probably died.
	ErrConnectionReset = errors.New("connection reset")
	// Tried to perform an operation on a path that doesn't exist on the device.
	ErrFileNotExist   = errors.New("file does not exist")
	ErrNotImplemented = errors.New("not implemented")
)

Sentinel error values used by this package

Functions

func FormatDeviceInfo

func FormatDeviceInfo(dd []DeviceInfo) string

Types

type Cmd

type Cmd struct {
	Path string
	Args []string
	// contains filtered or unexported fields
}

Cmd represents a command that can be executed on a device. Use Command to get an instance.

func (*Cmd) ExitCode

func (c *Cmd) ExitCode() int

func (*Cmd) Output

func (c *Cmd) Output() ([]byte, error)

Output returns the output send by the server as reply. Waits if not finished.

func (*Cmd) Run

func (c *Cmd) Run() error

Run starts and waits for command.

func (*Cmd) Start

func (c *Cmd) Start() error

Start sends command to device.

func (*Cmd) StartTimeout

func (c *Cmd) StartTimeout(timeout time.Time) error

func (*Cmd) Wait

func (c *Cmd) Wait() error

Wait waits for the servers response.

type Device

type Device struct {
	// contains filtered or unexported fields
}

Device communicates with a specific Android device. To get an instance, call Server.Device(serial).

func (*Device) Command

func (d *Device) Command(cmd string, args ...string) *Cmd

Command sets up a command to execute on device d. Command takes ownership of args.

func (*Device) CopyFile

func (d *Device) CopyFile(path string, r io.Reader, perms os.FileMode, modtime time.Time) (int, error)

CopyFile copies the contents of r writing them to path on the device.

func (*Device) DeviceInfo

func (d *Device) DeviceInfo() (DeviceInfo, error)

DeviceInfo queries the server for information on the current device.

func (*Device) DevicePath

func (d *Device) DevicePath() (string, error)

DevicePath returns the current devices path.

func (*Device) Forward

func (d *Device) Forward(local, remote ForwardSpec) error

Forward remote connection to local

func (*Device) ForwardList

func (d *Device) ForwardList() ([][2]ForwardSpec, error)

ForwardList returns list with struct ForwardPair If no device serial specified all devices's forward list will returned [2]ForwardSpec is {local, remote} serial is d.serial

func (*Device) ForwardRemove

func (d *Device) ForwardRemove(local ForwardSpec) error

ForwardRemove specified forward

func (*Device) ForwardRemoveAll

func (d *Device) ForwardRemoveAll() error

ForwardRemoveAll cancel all exists forwards

func (*Device) ForwardToFreePort

func (d *Device) ForwardToFreePort(remote ForwardSpec) (int, error)

ForwardToFreePort return random generated port If forward already exists, just return current forworded port

func (*Device) List

func (d *Device) List(path string) ([]DirEntry, error)

List lists the directory contents of path on file. move this to sync

func (*Device) OpenWrite

func (d *Device) OpenWrite(path string, perms os.FileMode, mtime time.Time) (io.WriteCloser, error)

OpenWrite opens the file at path on the device, creating it with the permissions specified by perms if necessary, and returns a writer that writes to the file. The files modification time will be set to mtime when the WriterCloser is closed. The zero value is TimeOfClose, which will use the time the Close method is called as the modification time. Deprecate this. Use CopyFile instead!

func (*Device) ReadFile

func (d *Device) ReadFile(path string) (io.ReadCloser, error)

ReadFile returns a a reader for the given path on the device.

func (*Device) Serial

func (d *Device) Serial() (string, error)

Serial returns the devices serial number. unnecessary?!

func (*Device) Stat

func (d *Device) Stat(path string) (DirEntry, error)

Stat returns filestats of path on device.

func (*Device) State

func (d *Device) State() (DeviceState, error)

func (*Device) String

func (d *Device) String() string

String returns the devices serial-number.

type DeviceInfo

type DeviceInfo struct {
	// Must be always set.
	Serial string
	// Product, device, and model are not set in the short form.
	Product string
	Model   string
	Device  string
	// Only set for devices connected via USB.
	USB string
}

func (DeviceInfo) IsUSB

func (d DeviceInfo) IsUSB() bool

IsUSB returns true if the device is connected via USB. remove?

type DeviceState

type DeviceState uint8

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
const (
	StateInvalid DeviceState = iota
	StateUnauthorized
	StateDisconnected
	StateOffline
	StateOnline
)

func (DeviceState) String

func (i DeviceState) String() string

type DeviceStateChangedEvent

type DeviceStateChangedEvent struct {
	Serial   string
	OldState DeviceState
	NewState DeviceState
}

DeviceStateChangedEvent represents a device state transition. Contains the device’s old and new states, but also provides methods to query the type of state transition.

func (DeviceStateChangedEvent) CameOnline

func (e DeviceStateChangedEvent) CameOnline() bool

CameOnline returns true if this event represents a device coming online.

func (DeviceStateChangedEvent) WentOffline

func (e DeviceStateChangedEvent) WentOffline() bool

WentOffline returns true if this event represents a device going offline.

type DeviceWatcher

type DeviceWatcher struct {
	// contains filtered or unexported fields
}

DeviceWatcher publishes device status change events. If the server dies while listening for events, it restarts the server.

func (*DeviceWatcher) C

func (w *DeviceWatcher) C() <-chan DeviceStateChangedEvent

C returns a channel than can be received on to get events. If an unrecoverable error occurs, or Shutdown is called, the channel will be closed.

func (*DeviceWatcher) Close

func (w *DeviceWatcher) Close() error

Close stops the watcher from listening for events and closes the channel returned from C. Don't double close a DeviceWatcher.

func (*DeviceWatcher) Err

func (w *DeviceWatcher) Err() error

Err returns the error that caused the channel returned by C to be closed, if C is closed. If C is not closed, its return value is undefined.

type DirEntry

type DirEntry struct {
	FName      string
	FMode      os.FileMode
	FSize      uint32
	ModifiedAt time.Time
}

DirEntry holds information about a directory entry on a device.

func ReadAllDirEntries

func ReadAllDirEntries(r io.Reader) ([]DirEntry, error)

ReadAllDirEntries reads directory entries into a slice, closes self, and returns any error. If err is non-nil, result will contain any entries read until the error occurred.

func (DirEntry) IsDir

func (de DirEntry) IsDir() bool

func (DirEntry) ModTime

func (de DirEntry) ModTime() time.Time

func (DirEntry) Mode

func (de DirEntry) Mode() os.FileMode

func (DirEntry) Name

func (de DirEntry) Name() string

func (DirEntry) Size

func (de DirEntry) Size() int64

func (DirEntry) Sys

func (de DirEntry) Sys() interface{}

type ForwardSpec

type ForwardSpec string

func (ForwardSpec) Port

func (f ForwardSpec) Port() int

Port returns -1 if the endpoint has no port.

func (ForwardSpec) Protocol

func (f ForwardSpec) Protocol() string

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server holds information needed to connect to a server repeatedly. Use New or NewDefault to create one.

func New

func New(path, host string, port int) (*Server, error)

New creates a new Server.

func NewDefault

func NewDefault() (*Server, error)

NewDefault creates a new Adb client that uses the default ServerConfig.

func (*Server) Device

func (s *Server) Device(serial string) *Device

Device takes a devices serial number and returns it. Returns nil on error.

func (*Server) Kill

func (s *Server) Kill() error

Kill tells the server to quit immediately.

func (*Server) ListDeviceSerials

func (s *Server) ListDeviceSerials() ([]string, error)

ListDeviceSerials returns the serial numbers of all attached devices.

func (*Server) ListDevices

func (s *Server) ListDevices() ([]DeviceInfo, error)

ListDevices returns the list of connected devices.

func (*Server) NewDeviceWatcher

func (s *Server) NewDeviceWatcher() (*DeviceWatcher, error)

NewDeviceWatcher starts a new device watcher.

func (*Server) Version

func (s *Server) Version() (int, error)

Version asks the adb server for its internal version number. TODO(jmh): Check server version format

type ShellExitError

type ShellExitError struct {
	Command  string
	ExitCode int
}

Rename CmdError?

func (ShellExitError) Error

func (s ShellExitError) Error() string

type UnexpectedStatusError

type UnexpectedStatusError struct {
	// contains filtered or unexported fields
}

func (*UnexpectedStatusError) Error

func (us *UnexpectedStatusError) Error() string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL