Documentation
¶
Index ¶
- func ClassifyDeviceError(deviceID string, connected, unauthorized []string) error
- func IsCriticalError(err error) bool
- func IsRetryableError(err error) bool
- func ListDevices(ctx context.Context, runner func(context.Context, string, ...string) *exec.Cmd) (connected []string, unauthorized []string, err error)
- func SanitizeShellArg(arg string) string
- type Controller
- func (c *Controller) CurrentApp(ctx context.Context) (string, error)
- func (c *Controller) DetectExpoScreenType(ctx context.Context) (string, error)
- func (c *Controller) DeviceID() string
- func (c *Controller) ExecuteAction(ctx context.Context, action types.Action) error
- func (c *Controller) FindElement(ctx context.Context, selectorStr string) (int, int, error)
- func (c *Controller) GetScreenDimensions(ctx context.Context) (int, int, error)
- func (c *Controller) GetUIHierarchy(ctx context.Context) (string, error)
- func (c *Controller) InputText(ctx context.Context, text string) error
- func (c *Controller) InputTextCtx(ctx context.Context, text string) error
- func (c *Controller) IsAppInstalled(ctx context.Context, packageName string) (bool, error)
- func (c *Controller) IsExpoApp(packageName string) bool
- func (c *Controller) IsReactNativeApp(ctx context.Context) (bool, error)
- func (c *Controller) LaunchApp(ctx context.Context, packageName string) error
- func (c *Controller) ListDevices(ctx context.Context) (connected []string, unauthorized []string, err error)
- func (c *Controller) RunCommand(ctx context.Context, args ...string) error
- func (c *Controller) RunCommandOutput(ctx context.Context, args ...string) (string, error)
- func (c *Controller) RunKeyevent(ctx context.Context, key string) error
- func (c *Controller) Swipe(ctx context.Context, x1, y1, x2, y2, durationMs int) error
- func (c *Controller) SwipeCtx(ctx context.Context, x1, y1, x2, y2, durationMs int) error
- func (c *Controller) Tap(ctx context.Context, x, y int) error
- func (c *Controller) TapCtx(ctx context.Context, x, y int) error
- type CriticalError
- type DeviceEvent
- type DeviceEventType
- type Monitor
- type MonitorConfig
- type RetryConfig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func ClassifyDeviceError ¶
ClassifyDeviceError creates a CriticalError from device state.
func IsCriticalError ¶
IsCriticalError determines if an error should stop the CADA loop. Critical errors: device disconnection, unauthorized, no device connected. Non-critical: transient failures (handled by retry logic).
func IsRetryableError ¶
IsRetryableError determines if an error should trigger a retry. Returns true for device connectivity issues, false for permanent errors.
func ListDevices ¶
func ListDevices(ctx context.Context, runner func(context.Context, string, ...string) *exec.Cmd) (connected []string, unauthorized []string, err error)
ListDevices is the internal implementation of device discovery. Returns lists of connected and unauthorized devices using the controller's runner.
func SanitizeShellArg ¶
SanitizeShellArg escapes arguments for adb shell execution to prevent command injection.
Types ¶
type Controller ¶
type Controller struct {
// contains filtered or unexported fields
}
Controller handles the bridge between the VIS agent and an Android device via ADB.
func New ¶
func New(ctx context.Context, deviceID string) (*Controller, error)
New creates a new ADB controller with default logger. Convenience function for E2E tests and simple use cases. Validates that the provided deviceID (if non-empty) is in the connected list.
func NewController ¶
func NewController(deviceID string, log *slog.Logger) *Controller
NewController creates a new ADB controller for a specific device.
func NewWithRunner ¶
func NewWithRunner(deviceID string, runner func(ctx context.Context, name string, args ...string) *exec.Cmd) *Controller
NewWithRunner creates a new ADB controller with a custom command runner.
func (*Controller) CurrentApp ¶
func (c *Controller) CurrentApp(ctx context.Context) (string, error)
CurrentApp returns the package name of the current foreground app. Uses 'adb shell dumpsys window windows' to get the focused app.
func (*Controller) DetectExpoScreenType ¶
func (c *Controller) DetectExpoScreenType(ctx context.Context) (string, error)
DetectExpoScreenType attempts to identify Expo-specific screen states.
func (*Controller) DeviceID ¶
func (c *Controller) DeviceID() string
DeviceID returns the device ID this controller is connected to.
func (*Controller) ExecuteAction ¶
ExecuteAction performs a physical interaction on the device.
func (*Controller) FindElement ¶
FindElement searches the UI hierarchy for an element matching the selector (ID, text, or content-desc). FindElement finds coordinates using uiautomator XML parser.
func (*Controller) GetScreenDimensions ¶
GetScreenDimensions returns the physical width and height of the device screen.
func (*Controller) GetUIHierarchy ¶
func (c *Controller) GetUIHierarchy(ctx context.Context) (string, error)
GetUIHierarchy captures the UI hierarchy via UIAutomator dump and returns the XML. It first runs uiautomator dump on the device, then reads the output file.
func (*Controller) InputText ¶
func (c *Controller) InputText(ctx context.Context, text string) error
InputText types text on the device.
func (*Controller) InputTextCtx ¶
func (c *Controller) InputTextCtx(ctx context.Context, text string) error
InputTextCtx types text on the device with an explicit context for cancellation propagation.
func (*Controller) IsAppInstalled ¶
IsAppInstalled checks if an app package is installed on the device. Returns (true, nil) if installed, (false, nil) if not installed, and (false, error) on ADB failure.
func (*Controller) IsExpoApp ¶
func (c *Controller) IsExpoApp(packageName string) bool
IsExpoApp checks if a package name matches known Expo/React Native patterns.
func (*Controller) IsReactNativeApp ¶
func (c *Controller) IsReactNativeApp(ctx context.Context) (bool, error)
IsReactNativeApp checks if the current foreground app is a React Native app.
func (*Controller) LaunchApp ¶
func (c *Controller) LaunchApp(ctx context.Context, packageName string) error
LaunchApp launches an application by package name.
func (*Controller) ListDevices ¶
func (c *Controller) ListDevices(ctx context.Context) (connected []string, unauthorized []string, err error)
ListDevices returns lists of connected and unauthorized devices using the controller's runner.
func (*Controller) RunCommand ¶
func (c *Controller) RunCommand(ctx context.Context, args ...string) error
RunCommand executes a raw ADB command with automatic retry on transient failures.
func (*Controller) RunCommandOutput ¶
RunCommandOutput executes a raw ADB command and returns the stdout output. It uses the same retry logic as RunCommand but captures and returns stdout. Returns error if the command fails, including stderr in the error message.
func (*Controller) RunKeyevent ¶
func (c *Controller) RunKeyevent(ctx context.Context, key string) error
RunKeyevent sends a keycode event to the device.
func (*Controller) Swipe ¶
func (c *Controller) Swipe(ctx context.Context, x1, y1, x2, y2, durationMs int) error
Swipe performs a swipe gesture from (x1,y1) to (x2,y2) over the specified duration in milliseconds.
func (*Controller) SwipeCtx ¶
func (c *Controller) SwipeCtx(ctx context.Context, x1, y1, x2, y2, durationMs int) error
SwipeCtx performs a swipe gesture with an explicit context for cancellation propagation.
type CriticalError ¶
type CriticalError struct {
Inner error
Type string // "device_disconnected", "device_unauthorized", "no_device"
}
CriticalError represents errors that should stop execution.
func NewCriticalError ¶
func NewCriticalError(err error, errorType string) *CriticalError
NewCriticalError creates a critical error.
func (*CriticalError) Error ¶
func (e *CriticalError) Error() string
func (*CriticalError) Unwrap ¶
func (e *CriticalError) Unwrap() error
type DeviceEvent ¶
type DeviceEvent struct {
Type DeviceEventType
DeviceID string
Timestamp time.Time
}
DeviceEvent represents a device connection state change.
type DeviceEventType ¶
type DeviceEventType string
DeviceEventType represents the type of device event.
const ( EventConnected DeviceEventType = "connected" EventDisconnected DeviceEventType = "disconnected" )
type Monitor ¶
type Monitor struct {
// contains filtered or unexported fields
}
Monitor watches for ADB device connection changes. It runs a background goroutine that polls `adb devices` and sends events on a channel when device status changes.
func NewMonitor ¶
func NewMonitor(cfg MonitorConfig) *Monitor
NewMonitor creates an ADB device monitor.
func (*Monitor) Events ¶
func (m *Monitor) Events() <-chan DeviceEvent
Events returns the channel for device events. Events are sent when device status changes (connected/disconnected/unauthorized).
func (*Monitor) IsConnected ¶
IsConnected returns the current connection status.
type MonitorConfig ¶
type MonitorConfig struct {
DeviceID string // Target device ID (empty for all devices)
PollInterval time.Duration // How often to check device status
}
MonitorConfig configures the device monitor.
func DefaultMonitorConfig ¶
func DefaultMonitorConfig() MonitorConfig
DefaultMonitorConfig returns sensible defaults.
type RetryConfig ¶
type RetryConfig struct {
MaxAttempts int // Maximum number of attempts (including first)
BaseDelay time.Duration // Initial delay between retries
MaxDelay time.Duration // Maximum delay between retries
JitterFactor float64 // Random jitter as fraction of delay (0.0-1.0)
}
RetryConfig configures retry behavior for ADB operations.
func DefaultRetryConfig ¶
func DefaultRetryConfig() RetryConfig
DefaultRetryConfig returns sensible defaults for ADB operations.