device

package
v0.2.0-beta.1 Latest Latest
Warning

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

Go to latest
Published: Sep 4, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package device defines the platform-neutral device contract.

Version v0 is deliberately declarations-only: session selection, acquisition, transport, and platform behavior belong to later packages and slices.

Index

Constants

View Source
const ContractVersionV0 = "v0"

Variables

View Source
var ErrUnsupported = errors.New("device: operation not supported on this platform")

ErrUnsupported is what a driver returns for an operation its platform cannot perform. The Driver surface is platform-neutral, so every implementation has methods it cannot answer; the sentinel is what lets a caller tell "this platform will never do that" apart from "that failed on the device".

An implementation that returns this for an operation must also report the operation unsupported in Capabilities, so preflight can refuse a flow before it runs rather than halfway through.

Functions

func ValidateRecordingSink

func ValidateRecordingSink(sink string) (base string, err error)

ValidateRecordingSink guards the untrusted screen-recording output path before it reaches `adb shell screenrecord`, `adb pull`, or `xcrun simctl io recordVideo`. The recording sink is flow-controlled input, so it is validated at this trust boundary: the whole path must not start with '-' (argv injection) and the basename must be shell-safe (command injection via the on-device shell). It returns the safe basename for callers that build an on-device path (e.g. /sdcard/<base>) from it.

Types

type AddMediaRequest

type AddMediaRequest struct {
	Files []MediaFile `json:"files"`
}

type AirplaneModeRequest

type AirplaneModeRequest struct {
	Enabled bool `json:"enabled"`
}

type AppRequest

type AppRequest struct {
	AppID string `json:"app_id"`
}

type Artifact

type Artifact struct {
	Kind     string            `json:"kind"`
	Path     string            `json:"path"`
	Metadata map[string]string `json:"metadata,omitempty"`
}

type ArtifactRequest

type ArtifactRequest struct {
	OutputDirectory string `json:"output_directory"`
	AppID           string `json:"app_id,omitempty"`
}

type Bounds

type Bounds struct {
	X      int `json:"x"`
	Y      int `json:"y"`
	Width  int `json:"width"`
	Height int `json:"height"`
}

type Browser

type Browser string

type Capabilities

type Capabilities struct {
	Platform Platform        `json:"platform"`
	Features map[string]bool `json:"features"`
}

type CaptureID

type CaptureID string

type ChromeDevToolsRequest

type ChromeDevToolsRequest struct {
	Enabled bool `json:"enabled"`
}

type ContentDescriptorRequest

type ContentDescriptorRequest struct {
	AppIDs                  []string `json:"app_ids,omitempty"`
	ExcludeKeyboardElements bool     `json:"exclude_keyboard_elements"`
}

type DeviceInfo

type DeviceInfo struct {
	Platform     Platform `json:"platform"`
	WidthPixels  int      `json:"width_pixels"`
	HeightPixels int      `json:"height_pixels"`
	WidthGrid    int      `json:"width_grid"`
	HeightGrid   int      `json:"height_grid"`
}

type DeviceLogRequest

type DeviceLogRequest struct {
	OutputDirectory string `json:"output_directory"`
	AppID           string `json:"app_id,omitempty"`
}

type Direction

type Direction string

type Driver

type Driver interface {
	Name() string
	Open(context.Context) error
	Close(context.Context) error
	DeviceInfo(context.Context) (DeviceInfo, error)
	LaunchApp(context.Context, LaunchAppRequest) error
	StopApp(context.Context, AppRequest) error
	KillApp(context.Context, AppRequest) error
	ClearAppState(context.Context, AppRequest) error
	ClearKeychain(context.Context) error
	Tap(context.Context, TapRequest) error
	LongPress(context.Context, LongPressRequest) error
	PressKey(context.Context, PressKeyRequest) error
	ContentDescriptor(context.Context, ContentDescriptorRequest) (TreeNode, error)
	ScrollVertical(context.Context, ScrollVerticalRequest) error
	IsKeyboardVisible(context.Context, KeyboardRequest) (bool, error)
	Swipe(context.Context, SwipeRequest) error
	BackPress(context.Context) error
	InputText(context.Context, InputTextRequest) error
	OpenLink(context.Context, OpenLinkRequest) error
	HideKeyboard(context.Context) error
	TakeScreenshot(context.Context, ScreenshotRequest) ([]byte, error)
	StartScreenRecording(context.Context, ScreenRecordingRequest) (CaptureID, error)
	SetLocation(context.Context, Location) error
	SetOrientation(context.Context, Orientation) error
	EraseText(context.Context, EraseTextRequest) error
	SetProxy(context.Context, Proxy) error
	ResetProxy(context.Context) error
	IsShutdown(context.Context) (bool, error)
	WaitUntilScreenIsStatic(context.Context, ScreenStaticRequest) (bool, error)
	WaitForAppToSettle(context.Context, SettleRequest) (*ViewHierarchy, error)
	Capabilities() Capabilities
	SetPermissions(context.Context, PermissionsRequest) error
	AddMedia(context.Context, AddMediaRequest) error
	IsAirplaneModeEnabled(context.Context) (bool, error)
	SetAirplaneMode(context.Context, AirplaneModeRequest) error
	SetAndroidChromeDevToolsEnabled(context.Context, ChromeDevToolsRequest) error
	QueryOnDeviceElements(context.Context, QueryRequest) ([]TreeNode, error)
	StartDeviceLogCapture(context.Context, DeviceLogRequest) (CaptureID, error)
	StopDeviceLogCapture(context.Context, CaptureID) ([]Artifact, error)
	CollectCrashArtifacts(context.Context, ArtifactRequest) ([]Artifact, error)
}

Driver is the frozen v0 platform-neutral behavior surface. Implementations must preserve context cancellation and may not reinterpret a nil settling result as proof that the device settled.

type EraseTextRequest

type EraseTextRequest struct {
	CharactersToErase uint32   `json:"characters_to_erase"`
	AppIDs            []string `json:"app_ids,omitempty"`
}

type IOSRouteV0

type IOSRouteV0 struct {
	Name            string `json:"name"`
	Method          string `json:"method"`
	Path            string `json:"path"`
	RequestLocation string `json:"request_location"`
	RequestSchema   string `json:"request_schema"`
	ResponseSchema  string `json:"response_schema"`
	SuccessStatus   int    `json:"success_status"`
	ErrorSchema     string `json:"error_schema"`
	ErrorStatuses   []int  `json:"error_statuses"`
}

IOSRouteV0 is a data-only route descriptor shared by the host client and the Swift runner implementation. It describes a contract; it performs no I/O.

func IOSRoutesContractV0

func IOSRoutesContractV0() []IOSRouteV0

IOSRoutesContractV0 returns a deep copy so callers cannot mutate the frozen process-wide contract.

type InputTextRequest

type InputTextRequest struct {
	Text   string   `json:"text"`
	AppIDs []string `json:"app_ids,omitempty"`
}

type KeyCode

type KeyCode string

type KeyboardRequest

type KeyboardRequest struct {
	AppIDs []string `json:"app_ids,omitempty"`
}

type LaunchAppRequest

type LaunchAppRequest struct {
	AppID     string           `json:"app_id"`
	Arguments []LaunchArgument `json:"arguments,omitempty"`
}

type LaunchArgument

type LaunchArgument struct {
	Key   string `json:"key"`
	Value string `json:"value"`
	Type  string `json:"type"`
}

type Location

type Location struct {
	Latitude  float64 `json:"latitude"`
	Longitude float64 `json:"longitude"`
}

type LongPressRequest

type LongPressRequest struct {
	Point          Point `json:"point"`
	DurationMillis int64 `json:"duration_millis"`
}

type MediaFile

type MediaFile struct {
	Path string `json:"path"`
}

type OpenLinkRequest

type OpenLinkRequest struct {
	Link       string  `json:"link"`
	AppID      string  `json:"app_id,omitempty"`
	AutoVerify bool    `json:"auto_verify"`
	Browser    Browser `json:"browser,omitempty"`
}

type Orientation

type Orientation string

type OrientationReader

type OrientationReader interface {
	CurrentOrientation(context.Context) (Orientation, error)
}

OrientationReader is an optional read-only extension used when a caller needs the device's actual rotation alongside captured screen content.

type PermissionsRequest

type PermissionsRequest struct {
	AppID       string            `json:"app_id"`
	Permissions map[string]string `json:"permissions"`
}

type Platform

type Platform string

type Point

type Point struct {
	X float64 `json:"x"`
	Y float64 `json:"y"`
}

type PressKeyRequest

type PressKeyRequest struct {
	Code   KeyCode  `json:"code"`
	AppIDs []string `json:"app_ids,omitempty"`
}

type Proxy

type Proxy struct {
	Host string `json:"host"`
	Port uint16 `json:"port"`
}

type QueryRequest

type QueryRequest struct {
	Expression string   `json:"expression"`
	AppIDs     []string `json:"app_ids,omitempty"`
}

type RetryableError

type RetryableError interface {
	error
	Retryable() bool
}

RetryableError is a driver error that can say whether resending the same request could plausibly succeed. A driver answering "this cannot work as posed" -- a runner precondition, say -- implements it, so a platform-neutral caller can tell a condition that will repeat from one worth another attempt without importing the platform package.

Implementing it is optional. A driver whose errors do not answer the question gets the older behavior: a caller retries or reports, and cannot tell the two apart. Today internal/ios answers it, because its runner refuses a request whose precondition fails. internal/android does not, and nothing is lost by that yet: its agent reads the accessibility hierarchy through UiAutomation across every window, so it has no foreground precondition to refuse on.

type RuntimePreflighter

type RuntimePreflighter interface {
	PreflightRuntime(context.Context, RuntimeRequirements) error
}

RuntimePreflighter is an optional, read-only extension to Driver. A driver implements it when static platform capabilities are not enough to decide support, such as an operation that requires a minimum device OS version. Implementations must not mutate the device.

type RuntimeRequirements

type RuntimeRequirements struct {
	Commands []string
}

RuntimeRequirements are the command-level facts a prepared run needs from its selected device. They are passed only to optional RuntimePreflighters, before Driver.Open, so device-version constraints can fail before installing helpers, granting permissions, or otherwise mutating the target.

type ScreenRecordingRequest

type ScreenRecordingRequest struct {
	OutputPath string `json:"output_path"`
}

type ScreenStaticRequest

type ScreenStaticRequest struct {
	TimeoutMillis int64 `json:"timeout_millis"`
}

type ScreenshotRequest

type ScreenshotRequest struct {
	Compressed bool `json:"compressed"`
}

type ScrollVerticalRequest

type ScrollVerticalRequest struct {
	Direction    Direction `json:"direction"`
	Amount       float64   `json:"amount"`
	ElementPoint *Point    `json:"element_point,omitempty"`
}

type SettleRequest

type SettleRequest struct {
	InitialHierarchy *ViewHierarchy `json:"initial_hierarchy,omitempty"`
	AppID            string         `json:"app_id,omitempty"`
	TimeoutMillis    *int64         `json:"timeout_millis,omitempty"`
}

SettleRequest models optional inputs explicitly. A nil result from WaitForAppToSettle means settling could not be confirmed.

type SwipeRequest

type SwipeRequest struct {
	Start          *Point    `json:"start,omitempty"`
	End            *Point    `json:"end,omitempty"`
	Direction      Direction `json:"direction,omitempty"`
	ElementPoint   *Point    `json:"element_point,omitempty"`
	DurationMillis int64     `json:"duration_millis"`
}

SwipeRequest represents the three v0 swipe shapes. Start/End, Direction, and ElementPoint are validated by the caller as mutually compatible modes.

type TapRequest

type TapRequest struct {
	Point Point `json:"point"`
}

type TreeNode

type TreeNode struct {
	Attributes map[string]string `json:"attributes"`
	Children   []TreeNode        `json:"children,omitempty"`
	Clickable  *bool             `json:"clickable,omitempty"`
	Enabled    *bool             `json:"enabled,omitempty"`
	Focused    *bool             `json:"focused,omitempty"`
	Checked    *bool             `json:"checked,omitempty"`
	Selected   *bool             `json:"selected,omitempty"`
}

type UiElement

type UiElement struct {
	Node   TreeNode `json:"node"`
	Bounds Bounds   `json:"bounds"`
}

type ViewHierarchy

type ViewHierarchy struct {
	Root TreeNode `json:"root"`
}

Jump to

Keyboard shortcuts

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