This commit is contained in:
张开元
2025-07-30 15:17:40 +08:00
parent 9ef98f828d
commit f580ea4168
6 changed files with 156 additions and 172 deletions

View File

@@ -291,14 +291,14 @@ func (s *StepMobile) SwipeRight(opts ...option.ActionOption) *StepMobile {
} }
// SIMSwipeWithDirection performs simulated swipe in specified direction with random distance // SIMSwipeWithDirection performs simulated swipe in specified direction with random distance
func (s *StepMobile) SIMSwipeWithDirection(direction string, startX, startY, minDistance, maxDistance float64, opts ...option.ActionOption) *StepMobile { func (s *StepMobile) SIMSwipeWithDirection(direction string, fromX, fromY, simMinDistance, simMaxDistance float64, opts ...option.ActionOption) *StepMobile {
// Create params map for SIMSwipeWithDirection // Create params map for SIMSwipeWithDirection
params := map[string]interface{}{ params := map[string]interface{}{
"direction": direction, "direction": direction,
"start_x": startX, "from_x": fromX,
"start_y": startY, "from_y": fromY,
"min_distance": minDistance, "sim_min_distance": simMinDistance,
"max_distance": maxDistance, "sim_max_distance": simMaxDistance,
} }
action := option.MobileAction{ action := option.MobileAction{
@@ -312,16 +312,16 @@ func (s *StepMobile) SIMSwipeWithDirection(direction string, startX, startY, min
} }
// SIMSwipeInArea performs simulated swipe in specified area with direction and random distance // SIMSwipeInArea performs simulated swipe in specified area with direction and random distance
func (s *StepMobile) SIMSwipeInArea(direction string, areaStartX, areaStartY, areaEndX, areaEndY, minDistance, maxDistance float64, opts ...option.ActionOption) *StepMobile { func (s *StepMobile) SIMSwipeInArea(direction string, simAreaStartX, simAreaStartY, simAreaEndX, simAreaEndY, simMinDistance, simMaxDistance float64, opts ...option.ActionOption) *StepMobile {
// Create params map for SIMSwipeInArea // Create params map for SIMSwipeInArea
params := map[string]interface{}{ params := map[string]interface{}{
"direction": direction, "direction": direction,
"area_start_x": areaStartX, "sim_area_start_x": simAreaStartX,
"area_start_y": areaStartY, "sim_area_start_y": simAreaStartY,
"area_end_x": areaEndX, "sim_area_end_x": simAreaEndX,
"area_end_y": areaEndY, "sim_area_end_y": simAreaEndY,
"min_distance": minDistance, "sim_min_distance": simMinDistance,
"max_distance": maxDistance, "sim_max_distance": simMaxDistance,
} }
action := option.MobileAction{ action := option.MobileAction{
@@ -335,13 +335,13 @@ func (s *StepMobile) SIMSwipeInArea(direction string, areaStartX, areaStartY, ar
} }
// SIMSwipeFromPointToPoint performs simulated swipe from point to point // SIMSwipeFromPointToPoint performs simulated swipe from point to point
func (s *StepMobile) SIMSwipeFromPointToPoint(startX, startY, endX, endY float64, opts ...option.ActionOption) *StepMobile { func (s *StepMobile) SIMSwipeFromPointToPoint(fromX, fromY, toX, toY float64, opts ...option.ActionOption) *StepMobile {
// Create params map for SIMSwipeFromPointToPoint // Create params map for SIMSwipeFromPointToPoint
params := map[string]interface{}{ params := map[string]interface{}{
"start_x": startX, "from_x": fromX,
"start_y": startY, "from_y": fromY,
"end_x": endX, "to_x": toX,
"end_y": endY, "to_y": toY,
} }
action := option.MobileAction{ action := option.MobileAction{

View File

@@ -1273,26 +1273,3 @@ func (ad *ADBDriver) SecondaryClick(x, y float64) (err error) {
func (ad *ADBDriver) SecondaryClickBySelector(selector string, options ...option.ActionOption) (err error) { func (ad *ADBDriver) SecondaryClickBySelector(selector string, options ...option.ActionOption) (err error) {
return err return err
} }
// SIMSupport interface implementation for ADBDriver
// These methods return "not supported" errors since SIM functionality is only available in UIA2Driver
func (ad *ADBDriver) SIMClickAtPoint(x, y float64, opts ...option.ActionOption) error {
return fmt.Errorf("SIMClickAtPoint is not supported in ADBDriver, please use UIA2Driver instead")
}
func (ad *ADBDriver) SIMSwipeWithDirection(direction string, startX, startY, minDistance, maxDistance float64, opts ...option.ActionOption) error {
return fmt.Errorf("SIMSwipeWithDirection is not supported in ADBDriver, please use UIA2Driver instead")
}
func (ad *ADBDriver) SIMSwipeInArea(direction string, areaStartX, areaStartY, areaEndX, areaEndY, minDistance, maxDistance float64, opts ...option.ActionOption) error {
return fmt.Errorf("SIMSwipeInArea is not supported in ADBDriver, please use UIA2Driver instead")
}
func (ad *ADBDriver) SIMSwipeFromPointToPoint(startX, startY, endX, endY float64, opts ...option.ActionOption) error {
return fmt.Errorf("SIMSwipeFromPointToPoint is not supported in ADBDriver, please use UIA2Driver instead")
}
func (ad *ADBDriver) SIMInput(text string, opts ...option.ActionOption) error {
return fmt.Errorf("SIMInput is not supported in ADBDriver, please use UIA2Driver instead")
}

View File

@@ -555,10 +555,10 @@ func (ud *UIA2Driver) TouchByEvents(events []types.TouchEvent, opts ...option.Ac
// SwipeWithDirection 向指定方向滑动任意距离 // SwipeWithDirection 向指定方向滑动任意距离
// direction: 滑动方向 ("up", "down", "left", "right") // direction: 滑动方向 ("up", "down", "left", "right")
// startX, startY: 起始坐标 // fromX, fromY: 起始坐标
// minDistance, maxDistance: 距离范围,如果相等则为固定距离,否则为随机距离 // simMinDistance, simMaxDistance: 距离范围,如果相等则为固定距离,否则为随机距离
func (ud *UIA2Driver) SIMSwipeWithDirection(direction string, startX, startY, minDistance, maxDistance float64, opts ...option.ActionOption) error { func (ud *UIA2Driver) SIMSwipeWithDirection(direction string, fromX, fromY, simMinDistance, simMaxDistance float64, opts ...option.ActionOption) error {
absStartX, absStartY, err := convertToAbsolutePoint(ud, startX, startY) absStartX, absStartY, err := convertToAbsolutePoint(ud, fromX, fromY)
if err != nil { if err != nil {
return err return err
} }
@@ -568,7 +568,7 @@ func (ud *UIA2Driver) SIMSwipeWithDirection(direction string, startX, startY, mi
log.Info().Str("direction", direction). log.Info().Str("direction", direction).
Float64("startX", absStartX).Float64("startY", absStartY). Float64("startX", absStartX).Float64("startY", absStartY).
Float64("minDistance", minDistance).Float64("maxDistance", maxDistance). Float64("minDistance", simMinDistance).Float64("maxDistance", simMaxDistance).
Str("deviceModel", deviceModel). Str("deviceModel", deviceModel).
Int("deviceID", deviceParams.DeviceID). Int("deviceID", deviceParams.DeviceID).
Float64("pressure", deviceParams.Pressure). Float64("pressure", deviceParams.Pressure).
@@ -595,7 +595,7 @@ func (ud *UIA2Driver) SIMSwipeWithDirection(direction string, startX, startY, mi
// 使用滑动仿真算法生成触摸事件序列 // 使用滑动仿真算法生成触摸事件序列
events, err := simulator.GenerateSlideWithRandomDistance( events, err := simulator.GenerateSlideWithRandomDistance(
absStartX, absStartY, slideDirection, minDistance, maxDistance, absStartX, absStartY, slideDirection, simMinDistance, simMaxDistance,
deviceParams.DeviceID, deviceParams.Pressure, deviceParams.Size) deviceParams.DeviceID, deviceParams.Pressure, deviceParams.Size)
if err != nil { if err != nil {
return fmt.Errorf("generate slide events failed: %v", err) return fmt.Errorf("generate slide events failed: %v", err)
@@ -607,15 +607,15 @@ func (ud *UIA2Driver) SIMSwipeWithDirection(direction string, startX, startY, mi
// SwipeInArea 在指定区域内向指定方向滑动任意距离 // SwipeInArea 在指定区域内向指定方向滑动任意距离
// direction: 滑动方向 ("up", "down", "left", "right") // direction: 滑动方向 ("up", "down", "left", "right")
// areaStartX, areaStartY, areaEndX, areaEndY: 区域范围(相对坐标) // simAreaStartX, simAreaStartY, simAreaEndX, simAreaEndY: 区域范围(相对坐标)
// minDistance, maxDistance: 距离范围,如果相等则为固定距离,否则为随机距离 // simMinDistance, simMaxDistance: 距离范围,如果相等则为固定距离,否则为随机距离
func (ud *UIA2Driver) SIMSwipeInArea(direction string, areaStartX, areaStartY, areaEndX, areaEndY, minDistance, maxDistance float64, opts ...option.ActionOption) error { func (ud *UIA2Driver) SIMSwipeInArea(direction string, simAreaStartX, simAreaStartY, simAreaEndX, simAreaEndY, simMinDistance, simMaxDistance float64, opts ...option.ActionOption) error {
// 转换区域坐标为绝对坐标 // 转换区域坐标为绝对坐标
absAreaStartX, absAreaStartY, err := convertToAbsolutePoint(ud, areaStartX, areaStartY) absAreaStartX, absAreaStartY, err := convertToAbsolutePoint(ud, simAreaStartX, simAreaStartY)
if err != nil { if err != nil {
return err return err
} }
absAreaEndX, absAreaEndY, err := convertToAbsolutePoint(ud, areaEndX, areaEndY) absAreaEndX, absAreaEndY, err := convertToAbsolutePoint(ud, simAreaEndX, simAreaEndY)
if err != nil { if err != nil {
return err return err
} }
@@ -635,7 +635,7 @@ func (ud *UIA2Driver) SIMSwipeInArea(direction string, areaStartX, areaStartY, a
log.Info().Str("direction", direction). log.Info().Str("direction", direction).
Float64("areaStartX", absAreaStartX).Float64("areaStartY", absAreaStartY). Float64("areaStartX", absAreaStartX).Float64("areaStartY", absAreaStartY).
Float64("areaEndX", absAreaEndX).Float64("areaEndY", absAreaEndY). Float64("areaEndX", absAreaEndX).Float64("areaEndY", absAreaEndY).
Float64("minDistance", minDistance).Float64("maxDistance", maxDistance). Float64("minDistance", simMinDistance).Float64("maxDistance", simMaxDistance).
Str("deviceModel", deviceModel). Str("deviceModel", deviceModel).
Int("deviceID", deviceParams.DeviceID). Int("deviceID", deviceParams.DeviceID).
Float64("pressure", deviceParams.Pressure). Float64("pressure", deviceParams.Pressure).
@@ -663,7 +663,7 @@ func (ud *UIA2Driver) SIMSwipeInArea(direction string, areaStartX, areaStartY, a
// 使用滑动仿真算法生成区域内滑动的触摸事件序列 // 使用滑动仿真算法生成区域内滑动的触摸事件序列
events, err := simulator.GenerateSlideInArea( events, err := simulator.GenerateSlideInArea(
absAreaStartX, absAreaStartY, absAreaEndX, absAreaEndY, absAreaStartX, absAreaStartY, absAreaEndX, absAreaEndY,
slideDirection, minDistance, maxDistance, slideDirection, simMinDistance, simMaxDistance,
deviceParams.DeviceID, deviceParams.Pressure, deviceParams.Size) deviceParams.DeviceID, deviceParams.Pressure, deviceParams.Size)
if err != nil { if err != nil {
return fmt.Errorf("generate slide in area events failed: %v", err) return fmt.Errorf("generate slide in area events failed: %v", err)
@@ -674,15 +674,15 @@ func (ud *UIA2Driver) SIMSwipeInArea(direction string, areaStartX, areaStartY, a
} }
// SwipeFromPointToPoint 指定起始点和结束点进行滑动 // SwipeFromPointToPoint 指定起始点和结束点进行滑动
// startX, startY: 起始坐标(相对坐标) // fromX, fromY: 起始坐标(相对坐标)
// endX, endY: 结束坐标(相对坐标) // toX, toY: 结束坐标(相对坐标)
func (ud *UIA2Driver) SIMSwipeFromPointToPoint(startX, startY, endX, endY float64, opts ...option.ActionOption) error { func (ud *UIA2Driver) SIMSwipeFromPointToPoint(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error {
// 转换起始点和结束点为绝对坐标 // 转换起始点和结束点为绝对坐标
absStartX, absStartY, err := convertToAbsolutePoint(ud, startX, startY) absStartX, absStartY, err := convertToAbsolutePoint(ud, fromX, fromY)
if err != nil { if err != nil {
return err return err
} }
absEndX, absEndY, err := convertToAbsolutePoint(ud, endX, endY) absEndX, absEndY, err := convertToAbsolutePoint(ud, toX, toY)
if err != nil { if err != nil {
return err return err
} }

View File

@@ -18,7 +18,6 @@ var (
// Ensure drivers implement SIMSupport interface // Ensure drivers implement SIMSupport interface
_ SIMSupport = (*UIA2Driver)(nil) _ SIMSupport = (*UIA2Driver)(nil)
_ SIMSupport = (*ADBDriver)(nil)
) )
// current implemeted driver: ADBDriver, UIA2Driver, WDADriver, HDCDriver // current implemeted driver: ADBDriver, UIA2Driver, WDADriver, HDCDriver
@@ -99,8 +98,8 @@ type IDriver interface {
// Any driver that supports simulated touch and input should implement this interface // Any driver that supports simulated touch and input should implement this interface
type SIMSupport interface { type SIMSupport interface {
SIMClickAtPoint(x, y float64, opts ...option.ActionOption) error SIMClickAtPoint(x, y float64, opts ...option.ActionOption) error
SIMSwipeWithDirection(direction string, startX, startY, minDistance, maxDistance float64, opts ...option.ActionOption) error SIMSwipeWithDirection(direction string, fromX, fromY, simMinDistance, simMaxDistance float64, opts ...option.ActionOption) error
SIMSwipeInArea(direction string, areaStartX, areaStartY, areaEndX, areaEndY, minDistance, maxDistance float64, opts ...option.ActionOption) error SIMSwipeInArea(direction string, simAreaStartX, simAreaStartY, simAreaEndX, simAreaEndY, simMinDistance, simMaxDistance float64, opts ...option.ActionOption) error
SIMSwipeFromPointToPoint(startX, startY, endX, endY float64, opts ...option.ActionOption) error SIMSwipeFromPointToPoint(fromX, fromY, toX, toY float64, opts ...option.ActionOption) error
SIMInput(text string, opts ...option.ActionOption) error SIMInput(text string, opts ...option.ActionOption) error
} }

View File

@@ -601,31 +601,31 @@ func (t *ToolSIMSwipeDirection) Implement() server.ToolHandlerFunc {
direction, validDirections) direction, validDirections)
} }
// Default values if not provided // Default values if not provided - use fromX/fromY instead of startX/startY
startX := unifiedReq.StartX fromX := unifiedReq.FromX
startY := unifiedReq.StartY fromY := unifiedReq.FromY
minDistance := unifiedReq.MinDistance simMinDistance := unifiedReq.SIMMinDistance
maxDistance := unifiedReq.MaxDistance simMaxDistance := unifiedReq.SIMMaxDistance
if startX == 0 { if fromX == 0 {
startX = 0.5 // default to center fromX = 0.5 // default to center
} }
if startY == 0 { if fromY == 0 {
startY = 0.5 // default to center fromY = 0.5 // default to center
} }
if minDistance == 0 { if simMinDistance == 0 {
minDistance = 100 // default minimum distance simMinDistance = 100 // default minimum distance
} }
if maxDistance == 0 { if simMaxDistance == 0 {
maxDistance = 300 // default maximum distance simMaxDistance = 300 // default maximum distance
} }
log.Info(). log.Info().
Str("direction", direction). Str("direction", direction).
Float64("startX", startX). Float64("startX", fromX).
Float64("startY", startY). Float64("startY", fromY).
Float64("minDistance", minDistance). Float64("minDistance", simMinDistance).
Float64("maxDistance", maxDistance). Float64("maxDistance", simMaxDistance).
Msg("performing simulated swipe with direction") Msg("performing simulated swipe with direction")
// Build all options from request arguments // Build all options from request arguments
@@ -633,7 +633,7 @@ func (t *ToolSIMSwipeDirection) Implement() server.ToolHandlerFunc {
// Call the underlying SIMSwipeWithDirection method (check if driver supports SIM) // Call the underlying SIMSwipeWithDirection method (check if driver supports SIM)
if simDriver, ok := driverExt.IDriver.(SIMSupport); ok { if simDriver, ok := driverExt.IDriver.(SIMSupport); ok {
err = simDriver.SIMSwipeWithDirection(direction, startX, startY, minDistance, maxDistance, opts...) err = simDriver.SIMSwipeWithDirection(direction, fromX, fromY, simMinDistance, simMaxDistance, opts...)
if err != nil { if err != nil {
return NewMCPErrorResponse(fmt.Sprintf("Simulated swipe failed: %s", err.Error())), err return NewMCPErrorResponse(fmt.Sprintf("Simulated swipe failed: %s", err.Error())), err
} }
@@ -642,19 +642,19 @@ func (t *ToolSIMSwipeDirection) Implement() server.ToolHandlerFunc {
} }
// Calculate actual distance for response (approximate) // Calculate actual distance for response (approximate)
actualDistance := minDistance actualDistance := simMinDistance
if maxDistance > minDistance { if simMaxDistance > simMinDistance {
actualDistance = minDistance + (maxDistance-minDistance)*0.5 // approximate middle value actualDistance = simMinDistance + (simMaxDistance-simMinDistance)*0.5 // approximate middle value
} }
message := fmt.Sprintf("Successfully performed simulated swipe %s from (%.2f, %.2f) with distance %.2f", message := fmt.Sprintf("Successfully performed simulated swipe %s from (%.2f, %.2f) with distance %.2f",
direction, startX, startY, actualDistance) direction, fromX, fromY, actualDistance)
returnData := ToolSIMSwipeDirection{ returnData := ToolSIMSwipeDirection{
Direction: direction, Direction: direction,
StartX: startX, StartX: fromX,
StartY: startY, StartY: fromY,
MinDistance: minDistance, MinDistance: simMinDistance,
MaxDistance: maxDistance, MaxDistance: simMaxDistance,
ActualDistance: actualDistance, ActualDistance: actualDistance,
} }
@@ -672,18 +672,18 @@ func (t *ToolSIMSwipeDirection) ConvertActionToCallToolRequest(action option.Mob
arguments["direction"] = direction arguments["direction"] = direction
} }
// Extract coordinates and distances // Extract coordinates and distances - use new field names directly
if startX, exists := paramsMap["start_x"]; exists { if fromX, exists := paramsMap["from_x"]; exists {
arguments["start_x"] = startX arguments["from_x"] = fromX
} }
if startY, exists := paramsMap["start_y"]; exists { if fromY, exists := paramsMap["from_y"]; exists {
arguments["start_y"] = startY arguments["from_y"] = fromY
} }
if minDistance, exists := paramsMap["min_distance"]; exists { if minDistance, exists := paramsMap["sim_min_distance"]; exists {
arguments["min_distance"] = minDistance arguments["sim_min_distance"] = minDistance
} }
if maxDistance, exists := paramsMap["max_distance"]; exists { if maxDistance, exists := paramsMap["sim_max_distance"]; exists {
arguments["max_distance"] = maxDistance arguments["sim_max_distance"] = maxDistance
} }
// Add duration and press duration from options // Add duration and press duration from options
@@ -753,30 +753,30 @@ func (t *ToolSIMSwipeInArea) Implement() server.ToolHandlerFunc {
direction, validDirections) direction, validDirections)
} }
// Get area coordinates // Get area coordinates - use SIM-prefixed fields
areaStartX := unifiedReq.AreaStartX simAreaStartX := unifiedReq.SIMAreaStartX
areaStartY := unifiedReq.AreaStartY simAreaStartY := unifiedReq.SIMAreaStartY
areaEndX := unifiedReq.AreaEndX simAreaEndX := unifiedReq.SIMAreaEndX
areaEndY := unifiedReq.AreaEndY simAreaEndY := unifiedReq.SIMAreaEndY
minDistance := unifiedReq.MinDistance simMinDistance := unifiedReq.SIMMinDistance
maxDistance := unifiedReq.MaxDistance simMaxDistance := unifiedReq.SIMMaxDistance
// Default values // Default values
if minDistance == 0 { if simMinDistance == 0 {
minDistance = 100 simMinDistance = 100
} }
if maxDistance == 0 { if simMaxDistance == 0 {
maxDistance = 300 simMaxDistance = 300
} }
log.Info(). log.Info().
Str("direction", direction). Str("direction", direction).
Float64("areaStartX", areaStartX). Float64("areaStartX", simAreaStartX).
Float64("areaStartY", areaStartY). Float64("areaStartY", simAreaStartY).
Float64("areaEndX", areaEndX). Float64("areaEndX", simAreaEndX).
Float64("areaEndY", areaEndY). Float64("areaEndY", simAreaEndY).
Float64("minDistance", minDistance). Float64("minDistance", simMinDistance).
Float64("maxDistance", maxDistance). Float64("maxDistance", simMaxDistance).
Msg("performing simulated swipe in area") Msg("performing simulated swipe in area")
// Build all options from request arguments // Build all options from request arguments
@@ -784,7 +784,7 @@ func (t *ToolSIMSwipeInArea) Implement() server.ToolHandlerFunc {
// Call the underlying SIMSwipeInArea method (check if driver supports SIM) // Call the underlying SIMSwipeInArea method (check if driver supports SIM)
if simDriver, ok := driverExt.IDriver.(SIMSupport); ok { if simDriver, ok := driverExt.IDriver.(SIMSupport); ok {
err = simDriver.SIMSwipeInArea(direction, areaStartX, areaStartY, areaEndX, areaEndY, minDistance, maxDistance, opts...) err = simDriver.SIMSwipeInArea(direction, simAreaStartX, simAreaStartY, simAreaEndX, simAreaEndY, simMinDistance, simMaxDistance, opts...)
if err != nil { if err != nil {
return NewMCPErrorResponse(fmt.Sprintf("Simulated swipe in area failed: %s", err.Error())), err return NewMCPErrorResponse(fmt.Sprintf("Simulated swipe in area failed: %s", err.Error())), err
} }
@@ -793,15 +793,15 @@ func (t *ToolSIMSwipeInArea) Implement() server.ToolHandlerFunc {
} }
message := fmt.Sprintf("Successfully performed simulated swipe %s in area (%.2f,%.2f)-(%.2f,%.2f)", message := fmt.Sprintf("Successfully performed simulated swipe %s in area (%.2f,%.2f)-(%.2f,%.2f)",
direction, areaStartX, areaStartY, areaEndX, areaEndY) direction, simAreaStartX, simAreaStartY, simAreaEndX, simAreaEndY)
returnData := ToolSIMSwipeInArea{ returnData := ToolSIMSwipeInArea{
Direction: direction, Direction: direction,
AreaStartX: areaStartX, AreaStartX: simAreaStartX,
AreaStartY: areaStartY, AreaStartY: simAreaStartY,
AreaEndX: areaEndX, AreaEndX: simAreaEndX,
AreaEndY: areaEndY, AreaEndY: simAreaEndY,
MinDistance: minDistance, MinDistance: simMinDistance,
MaxDistance: maxDistance, MaxDistance: simMaxDistance,
} }
return NewMCPSuccessResponse(message, &returnData), nil return NewMCPSuccessResponse(message, &returnData), nil
@@ -818,24 +818,24 @@ func (t *ToolSIMSwipeInArea) ConvertActionToCallToolRequest(action option.Mobile
arguments["direction"] = direction arguments["direction"] = direction
} }
// Extract area coordinates and distances // Extract area coordinates and distances - use SIM-prefixed field names
if areaStartX, exists := paramsMap["area_start_x"]; exists { if areaStartX, exists := paramsMap["sim_area_start_x"]; exists {
arguments["area_start_x"] = areaStartX arguments["sim_area_start_x"] = areaStartX
} }
if areaStartY, exists := paramsMap["area_start_y"]; exists { if areaStartY, exists := paramsMap["sim_area_start_y"]; exists {
arguments["area_start_y"] = areaStartY arguments["sim_area_start_y"] = areaStartY
} }
if areaEndX, exists := paramsMap["area_end_x"]; exists { if areaEndX, exists := paramsMap["sim_area_end_x"]; exists {
arguments["area_end_x"] = areaEndX arguments["sim_area_end_x"] = areaEndX
} }
if areaEndY, exists := paramsMap["area_end_y"]; exists { if areaEndY, exists := paramsMap["sim_area_end_y"]; exists {
arguments["area_end_y"] = areaEndY arguments["sim_area_end_y"] = areaEndY
} }
if minDistance, exists := paramsMap["min_distance"]; exists { if minDistance, exists := paramsMap["sim_min_distance"]; exists {
arguments["min_distance"] = minDistance arguments["sim_min_distance"] = minDistance
} }
if maxDistance, exists := paramsMap["max_distance"]; exists { if maxDistance, exists := paramsMap["sim_max_distance"]; exists {
arguments["max_distance"] = maxDistance arguments["sim_max_distance"] = maxDistance
} }
// Add duration and press duration from options // Add duration and press duration from options
@@ -886,17 +886,17 @@ func (t *ToolSIMSwipeFromPointToPoint) Implement() server.ToolHandlerFunc {
return nil, err return nil, err
} }
// Get coordinates from arguments // Get coordinates from arguments - use fromX/fromY instead of startX/startY
startX := unifiedReq.StartX fromX := unifiedReq.FromX
startY := unifiedReq.StartY fromY := unifiedReq.FromY
endX := unifiedReq.ToX // Using existing ToX field toX := unifiedReq.ToX
endY := unifiedReq.ToY // Using existing ToY field toY := unifiedReq.ToY
log.Info(). log.Info().
Float64("startX", startX). Float64("startX", fromX).
Float64("startY", startY). Float64("startY", fromY).
Float64("endX", endX). Float64("endX", toX).
Float64("endY", endY). Float64("endY", toY).
Msg("performing simulated point to point swipe") Msg("performing simulated point to point swipe")
// Build all options from request arguments // Build all options from request arguments
@@ -904,7 +904,7 @@ func (t *ToolSIMSwipeFromPointToPoint) Implement() server.ToolHandlerFunc {
// Call the underlying SIMSwipeFromPointToPoint method (check if driver supports SIM) // Call the underlying SIMSwipeFromPointToPoint method (check if driver supports SIM)
if simDriver, ok := driverExt.IDriver.(SIMSupport); ok { if simDriver, ok := driverExt.IDriver.(SIMSupport); ok {
err = simDriver.SIMSwipeFromPointToPoint(startX, startY, endX, endY, opts...) err = simDriver.SIMSwipeFromPointToPoint(fromX, fromY, toX, toY, opts...)
if err != nil { if err != nil {
return NewMCPErrorResponse(fmt.Sprintf("Simulated point to point swipe failed: %s", err.Error())), err return NewMCPErrorResponse(fmt.Sprintf("Simulated point to point swipe failed: %s", err.Error())), err
} }
@@ -913,12 +913,12 @@ func (t *ToolSIMSwipeFromPointToPoint) Implement() server.ToolHandlerFunc {
} }
message := fmt.Sprintf("Successfully performed simulated swipe from (%.2f,%.2f) to (%.2f,%.2f)", message := fmt.Sprintf("Successfully performed simulated swipe from (%.2f,%.2f) to (%.2f,%.2f)",
startX, startY, endX, endY) fromX, fromY, toX, toY)
returnData := ToolSIMSwipeFromPointToPoint{ returnData := ToolSIMSwipeFromPointToPoint{
StartX: startX, StartX: fromX,
StartY: startY, StartY: fromY,
EndX: endX, EndX: toX,
EndY: endY, EndY: toY,
} }
return NewMCPSuccessResponse(message, &returnData), nil return NewMCPSuccessResponse(message, &returnData), nil
@@ -930,18 +930,18 @@ func (t *ToolSIMSwipeFromPointToPoint) ConvertActionToCallToolRequest(action opt
if paramsMap, ok := action.Params.(map[string]interface{}); ok { if paramsMap, ok := action.Params.(map[string]interface{}); ok {
arguments := map[string]any{} arguments := map[string]any{}
// Extract coordinates // Extract coordinates - use new field names directly
if startX, exists := paramsMap["start_x"]; exists { if fromX, exists := paramsMap["from_x"]; exists {
arguments["start_x"] = startX arguments["from_x"] = fromX
} }
if startY, exists := paramsMap["start_y"]; exists { if fromY, exists := paramsMap["from_y"]; exists {
arguments["start_y"] = startY arguments["from_y"] = fromY
} }
if endX, exists := paramsMap["end_x"]; exists { if toX, exists := paramsMap["to_x"]; exists {
arguments["to_x"] = endX // Map to existing ToX field arguments["to_x"] = toX
} }
if endY, exists := paramsMap["end_y"]; exists { if toY, exists := paramsMap["to_y"]; exists {
arguments["to_y"] = endY // Map to existing ToY field arguments["to_y"] = toY
} }
// Add duration and press duration from options // Add duration and press duration from options

View File

@@ -206,17 +206,18 @@ type ActionOptions struct {
PressDuration float64 `json:"press_duration,omitempty" yaml:"press_duration,omitempty" desc:"Press duration in seconds"` PressDuration float64 `json:"press_duration,omitempty" yaml:"press_duration,omitempty" desc:"Press duration in seconds"`
Steps int `json:"steps,omitempty" yaml:"steps,omitempty" desc:"Number of steps for action"` Steps int `json:"steps,omitempty" yaml:"steps,omitempty" desc:"Number of steps for action"`
Direction interface{} `json:"direction,omitempty" yaml:"direction,omitempty" desc:"Direction for swipe operations or custom coordinates"` Direction interface{} `json:"direction,omitempty" yaml:"direction,omitempty" desc:"Direction for swipe operations or custom coordinates"`
StartX float64 `json:"start_x,omitempty" yaml:"start_x,omitempty" desc:"Starting X coordinate for simulated swipe"`
StartY float64 `json:"start_y,omitempty" yaml:"start_y,omitempty" desc:"Starting Y coordinate for simulated swipe"` // SIM specific options with SIM prefix
MinDistance float64 `json:"min_distance,omitempty" yaml:"min_distance,omitempty" desc:"Minimum distance for simulated swipe"` SIMMinDistance float64 `json:"sim_min_distance,omitempty" yaml:"sim_min_distance,omitempty" desc:"Minimum distance for SIM simulated actions"`
MaxDistance float64 `json:"max_distance,omitempty" yaml:"max_distance,omitempty" desc:"Maximum distance for simulated swipe"` SIMMaxDistance float64 `json:"sim_max_distance,omitempty" yaml:"sim_max_distance,omitempty" desc:"Maximum distance for SIM simulated actions"`
AreaStartX float64 `json:"area_start_x,omitempty" yaml:"area_start_x,omitempty" desc:"Area starting X coordinate for simulated swipe"` SIMAreaStartX float64 `json:"sim_area_start_x,omitempty" yaml:"sim_area_start_x,omitempty" desc:"Area starting X coordinate for SIM simulated swipe"`
AreaStartY float64 `json:"area_start_y,omitempty" yaml:"area_start_y,omitempty" desc:"Area starting Y coordinate for simulated swipe"` SIMAreaStartY float64 `json:"sim_area_start_y,omitempty" yaml:"sim_area_start_y,omitempty" desc:"Area starting Y coordinate for SIM simulated swipe"`
AreaEndX float64 `json:"area_end_x,omitempty" yaml:"area_end_x,omitempty" desc:"Area ending X coordinate for simulated swipe"` SIMAreaEndX float64 `json:"sim_area_end_x,omitempty" yaml:"sim_area_end_x,omitempty" desc:"Area ending X coordinate for SIM simulated swipe"`
AreaEndY float64 `json:"area_end_y,omitempty" yaml:"area_end_y,omitempty" desc:"Area ending Y coordinate for simulated swipe"` SIMAreaEndY float64 `json:"sim_area_end_y,omitempty" yaml:"sim_area_end_y,omitempty" desc:"Area ending Y coordinate for SIM simulated swipe"`
Timeout int `json:"timeout,omitempty" yaml:"timeout,omitempty" desc:"Timeout in seconds for action execution"`
TimeLimit int `json:"time_limit,omitempty" yaml:"time_limit,omitempty" desc:"Time limit in seconds for action execution, stops gracefully when reached"` Timeout int `json:"timeout,omitempty" yaml:"timeout,omitempty" desc:"Timeout in seconds for action execution"`
Frequency int `json:"frequency,omitempty" yaml:"frequency,omitempty" desc:"Action frequency"` TimeLimit int `json:"time_limit,omitempty" yaml:"time_limit,omitempty" desc:"Time limit in seconds for action execution, stops gracefully when reached"`
Frequency int `json:"frequency,omitempty" yaml:"frequency,omitempty" desc:"Action frequency"`
ScreenOptions ScreenOptions
@@ -662,6 +663,13 @@ func (o *ActionOptions) GetMCPOptions(actionType ActionName) []mcp.ToolOption {
ACTION_Back: {"platform", "serial"}, ACTION_Back: {"platform", "serial"},
ACTION_ListPackages: {"platform", "serial"}, ACTION_ListPackages: {"platform", "serial"},
ACTION_ClosePopups: {"platform", "serial"}, ACTION_ClosePopups: {"platform", "serial"},
// SIM specific actions using fromX/fromY for startX/startY and SIM-prefixed fields
ACTION_SIMSwipeDirection: {"platform", "serial", "direction", "fromX", "fromY", "sim_min_distance", "sim_max_distance", "duration", "pressDuration"},
ACTION_SIMSwipeInArea: {"platform", "serial", "direction", "sim_area_start_x", "sim_area_start_y", "sim_area_end_x", "sim_area_end_y", "sim_min_distance", "sim_max_distance", "duration", "pressDuration"},
ACTION_SIMSwipeFromPointToPoint: {"platform", "serial", "fromX", "fromY", "toX", "toY", "duration", "pressDuration"},
ACTION_SIMClickAtPoint: {"platform", "serial", "x", "y", "duration", "pressDuration"},
ACTION_SIMInput: {"platform", "serial", "text", "frequency"},
} }
fields := fieldMappings[actionType] fields := fieldMappings[actionType]