adb

package module
v0.0.0-...-810a431 Latest Latest
Warning

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

Go to latest
Published: Jan 14, 2023 License: 0BSD Imports: 14 Imported by: 1

README

PkgGoDev

adb

This library aims at providing idiomatic adb bindings for go developers, in order to make it easier to write system tooling using golang. This tool tries to take guesswork out of arbitrarily shelling out to adb by providing a structured, thoroughly-tested wrapper for the adb functions most-likely to be used in a system program.

If adb must be installed in your path PATH. At this time, while this library may work on Windows or MacOS, only Linux is supported. If you would like to add support for Windows, MacOS, *BSD..., please Submit a Pull Request.

What is adb

adb, the Android Debug Bridge, is a command-line program which allows a user to remote-control and debug Android devices.

Supported adb functions

  • adb connect
  • adb disconnect
  • adb shell <input>s
  • adb kill-server
  • adb device
  • adb pull
  • adb install
  • adb push
  • adb reboot
  • adb shell input tap X Y
  • adb shell input swipe X1 Y1 X2 Y2 duration

Please note that as this is a purpose-driven project library, not all functionality of ADB is currently supported, but if you need functionality that's not currently supported, Feel free to Open an Issue or Submit a Pull Request

Helper functionality

  • In addition to using the shell commands, this library provides helper methods for stateful connections. That is, you can connect to a device and get back a handler object and call functions against it with better error handling.

  • In addition to the connection commands, this library also has helper functions for many common shell commands, including:

    • pm grant
    • am start
    • dumpsys
    • screencap
    • screenrecord
    • rm

Useful errors

All functions return a predefined error type, and it is highly recommended these errors are handled properly.

Context support

All calls into this library support go's context functionality. Therefore, blocking calls can time out according to the caller's needs, and the returned error should be checked to see if a timeout occurred (ErrExecTimeout).

Simple example

package main

import (
    "context"
    "fmt"
    "log"
    "time"

    "github.com/taigrr/adb"
)

func main() {
    ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
    defer cancel()
    // Equivalent to `adb connect 192.168.2.5` with a 10 second timeout
    opts := adb.Options{ Address: "192.168.2.5" }
    dev, err := adb.Connect(ctx, opts)
    if err != nil {
        log.Fatalf("unable to connect to device %s: %v", opts.Address, err)
    }
    defer dev.Disconnect()
    stdout, stderr, errCode, err := dev.Shell("ls")
    if err != nil {
        log.Fatalf("unable to shell into device %s: %v", opts.Address, err)
    }
    log.Printf("Stdout: %s\nStderr: %s\n, ErrCode: %d", stdout, stderr, errCode)
}

License

This project is licensed under the 0BSD License, written by Rob Landley. As such, you may use this library without restriction or attribution, but please don't pass it off as your own. Attribution, though not required, is appreciated.

By contributing, you agree all code submitted also falls under the License.

External resources

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// When an execution should have data but has none, but the exact error is
	// indeterminite, this error is returned
	ErrStdoutEmpty         = errors.New("stdout expected to contain data but was empty")
	ErrNotInstalled        = errors.New("adb is not installed or not in PATH")
	ErrCoordinatesNotFound = errors.New("coordinates for an input event are missing")
	ErrConnUSB             = errors.New("cannot call connect/disconnect to device using USB")
	ErrResolutionParseFail = errors.New("failed to parse screen size from input text")
	ErrUnspecified         = errors.New("an unknown error has occurred, please open an issue on GitHub")
)

Functions

func KillServer

func KillServer(ctx context.Context) error

Kill the ADB Server

Warning, this function call may cause inconsostency if not used properly. Killing the ADB server shouldn't ever technically be necessary, but if you do decide to use this function. note that it may invalidate all existing device structs. Older versions of Android don't play nicely with kill-server, and some may refuse following connection attempts if you don't disconnect from them before calling this function.

Types

type ConnOptions

type ConnOptions struct {
	Address  net.IPAddr
	Port     uint
	SerialNo Serial
}

Provides a connection string for Connect()

type Connection

type Connection int
const (
	USB Connection = iota
	Network
)

type Device

type Device struct {
	IsAuthorized bool
	SerialNo     Serial
	ConnType     Connection
	IP           net.IPAddr
	Port         uint
	FileHandle   string // TODO change this to a discrete type
}

Create a Device with Connect() or a slice with Devices()

Device contains the information necessary to connect to and communicate with a device

func Connect

func Connect(ctx context.Context, opts ConnOptions) (Device, error)

Connect to a device by IP:port.

This will return a Device struct, which can be used to call other methods. If the connection fails or cannot complete on time, Connect will return an error. TODO

func Devices

func Devices(ctx context.Context) ([]Device, error)

Equivalent to running `adb devices`.

This function returns a list of discovered devices, but note that they may not be connected. It is recommended to call IsConnected() against the device you're interested in using and connect if not already connected before proceeding.

func (Device) CaptureSequence

func (d Device) CaptureSequence(ctx context.Context) (t TapSequence, err error)

CaptureSequence allows you to capture and replay screen taps and swipes.

ctx, cancelFunc := context.WithCancel(context.TODO())

go dev.CaptureSequence(ctx) time.Sleep(time.Second * 30) cancelFunc()

func (Device) ConnString

func (d Device) ConnString() string

func (Device) Disconnect

func (d Device) Disconnect(ctx context.Context) error

Disconnect from a device.

If a device is already disconnected or otherwise not found, returns an error.

func (Device) GetScreenResolution

func (d Device) GetScreenResolution(ctx context.Context) (res Resolution, err error)

adb shell wm size Physical size: 1440x3120

func (Device) GoBack

func (d Device) GoBack(ctx context.Context) error

Equivalent to pressing the back button

Calls `input keyevent KEYCODE_BACK` under the hood

func (Device) GoHome

func (d Device) GoHome(ctx context.Context) error

Equivalent to pressing the home button

Calls `input keyevent KEYCODE_HOME` under the hood

func (Device) LongPress

func (d Device) LongPress(ctx context.Context, X, Y int) error

Simulates a long press

Under the hood, this calls swipe with the same start and end coordinates with a duration of 250ms

func (Device) Pull

func (d Device) Pull(ctx context.Context, src, dest string) error

Pulls a file from a Device

Returns an error if src does not exist, or if dest already exists or cannot be created

func (Device) Push

func (d Device) Push(ctx context.Context, src, dest string) error

Push a file to a Device.

Returns an error if src does not exist or there is an error copying the file.

func (Device) Reboot

func (d Device) Reboot(ctx context.Context) error

Attempts to reboot the device

Once the device reboots, you must manually reconnect. Returns an error if the device cannot be contacted

func (Device) Reconnect

func (d Device) Reconnect(ctx context.Context) (Device, error)

Connect to a previously discovered device.

This function is helpful when connecting to a device found from the Devices call or when reconnecting to a previously connected device.

func (Device) ReplayTapSequence

func (d Device) ReplayTapSequence(ctx context.Context, t TapSequence) error

func (Device) Root

func (d Device) Root(ctx context.Context) (success bool, err error)

Attempt to relaunch adb as root on the Device.

Note, this may not be possible on most devices. Returns an error if it can't be done. The device connection will stay established. Once adb is relaunched as root, it will stay root until rebooted. returns true if the device successfully relaunched as root

func (Device) Shell

func (d Device) Shell(ctx context.Context, command string) (stdout string, stderr string, ErrCode int, err error)

Shell allows you to run an arbitrary shell command against a device.

This function is useful if you need to run an obscure shell command or if you require functionality not provided by the exposed functions here. Instead of using Shell, please consider submitting a PR with the functionality you require.

func (Device) Swipe

func (d Device) Swipe(ctx context.Context, X1, Y1, X2, Y2 int, duration time.Duration) error

func (Device) SwitchApp

func (d Device) SwitchApp(ctx context.Context) error

Equivalent to pushing the app switcher. You probably want to call this twice.

Calls `input keyevent KEYCODE_APP_SWITCH` under the hood

func (Device) Tap

func (d Device) Tap(ctx context.Context, X, Y int) error

type Input

type Input interface {
	Play(d Device, ctx context.Context) error
	Length() time.Duration
	StartTime() time.Time
	EndTime() time.Time
}

type Resolution

type Resolution struct {
	Width  int
	Height int
}

type SeqType

type SeqType int
const (
	SeqSwipe SeqType = iota
	SeqTap
	SeqSleep
)

type SequenceImporter

type SequenceImporter struct {
	Duration time.Duration
	Type     SeqType
	X        int
	Y        int
	X1       int
	Y1       int
	X2       int
	Y2       int
	Start    time.Time
	End      time.Time
}

func (SequenceImporter) ToInput

func (si SequenceImporter) ToInput() Input

type SequenceSleep

type SequenceSleep struct {
	Duration time.Duration
	Type     SeqType
}

func (SequenceSleep) EndTime

func (s SequenceSleep) EndTime() time.Time

func (SequenceSleep) Length

func (s SequenceSleep) Length() time.Duration

func (SequenceSleep) Play

func (s SequenceSleep) Play(d Device, ctx context.Context) error

func (SequenceSleep) StartTime

func (s SequenceSleep) StartTime() time.Time

type SequenceSwipe

type SequenceSwipe struct {
	X1    int
	Y1    int
	X2    int
	Y2    int
	Start time.Time
	End   time.Time
	Type  SeqType
}

func (SequenceSwipe) EndTime

func (s SequenceSwipe) EndTime() time.Time

func (SequenceSwipe) Length

func (s SequenceSwipe) Length() time.Duration

func (SequenceSwipe) Play

func (s SequenceSwipe) Play(d Device, ctx context.Context) error

func (SequenceSwipe) StartTime

func (s SequenceSwipe) StartTime() time.Time

type SequenceTap

type SequenceTap struct {
	X     int
	Y     int
	Start time.Time
	End   time.Time
	Type  SeqType
}

func (SequenceTap) EndTime

func (s SequenceTap) EndTime() time.Time

func (SequenceTap) Length

func (s SequenceTap) Length() time.Duration

func (SequenceTap) Play

func (s SequenceTap) Play(d Device, ctx context.Context) error

func (SequenceTap) StartTime

func (s SequenceTap) StartTime() time.Time

type Serial

type Serial string

type TapSequence

type TapSequence struct {
	Events     []Input
	Resolution Resolution
}

func TapSequenceFromJSON

func TapSequenceFromJSON(j []byte) (TapSequence, error)

func (TapSequence) GetLength

func (t TapSequence) GetLength() time.Duration

GetLength returns the length of all Input events inside of a given TapSequence

This function is useful for devermining how long a context timeout should last when calling ReplayTapSequence

func (TapSequence) ShortenSleep

func (t TapSequence) ShortenSleep(scalar int) TapSequence

func (TapSequence) ToJSON

func (t TapSequence) ToJSON() []byte

type TapSequenceImporter

type TapSequenceImporter struct {
	Events     []SequenceImporter
	Resolution Resolution
}

Directories

Path Synopsis
examples
tapRecorder Module

Jump to

Keyboard shortcuts

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