@@ -60,13 +60,15 @@ export type AndroidDeviceOpt = {
60
60
usePhysicalDisplayIdForScreenshot ?: boolean ;
61
61
usePhysicalDisplayIdForDisplayLookup ?: boolean ;
62
62
customActions ?: DeviceAction < any > [ ] ;
63
+ screenshotResizeScale ?: number ;
63
64
} & AndroidDeviceInputOpt ;
64
65
65
66
export class AndroidDevice implements AbstractInterface {
66
67
private deviceId : string ;
67
68
private yadbPushed = false ;
68
69
private devicePixelRatio = 1 ;
69
70
private devicePixelRatioInitialized = false ;
71
+ private scalingRatio = 1 ; // Record scaling ratio for coordinate adjustment
70
72
private adb : ADB | null = null ;
71
73
private connectingAdb : Promise < ADB > | null = null ;
72
74
private destroyed = false ;
@@ -713,12 +715,28 @@ ${Object.keys(size)
713
715
const width = Number . parseInt ( match [ isLandscape ? 2 : 1 ] , 10 ) ;
714
716
const height = Number . parseInt ( match [ isLandscape ? 1 : 2 ] , 10 ) ;
715
717
716
- // Return physical pixels to match screenshot dimensions
717
- // This ensures AI coordinate conversion uses the same dimensions as the screenshot
718
+ // Determine scaling: use screenshotResizeScale if provided, otherwise use 1/devicePixelRatio
719
+ // Default is 1/dpr to scale down by device pixel ratio (e.g., dpr=3 -> scale=1/3)
720
+ const scale =
721
+ this . options ?. screenshotResizeScale ?? 1 / this . devicePixelRatio ;
722
+ this . scalingRatio = scale ;
723
+
724
+ // Apply scale to get logical dimensions for AI processing
725
+ // adjustCoordinates() will convert back to physical pixels when needed for touch operations
726
+ const logicalWidth = Math . round ( width * scale ) ;
727
+ const logicalHeight = Math . round ( height * scale ) ;
728
+
729
+ return {
730
+ width : logicalWidth ,
731
+ height : logicalHeight ,
732
+ } ;
733
+ }
734
+
735
+ private adjustCoordinates ( x : number , y : number ) : { x : number ; y : number } {
736
+ const scale = this . scalingRatio ;
718
737
return {
719
- width,
720
- height,
721
- dpr : this . devicePixelRatio ,
738
+ x : Math . round ( x / scale ) ,
739
+ y : Math . round ( y / scale ) ,
722
740
} ;
723
741
}
724
742
@@ -1170,17 +1188,20 @@ ${Object.keys(size)
1170
1188
async mouseClick ( x : number , y : number ) : Promise < void > {
1171
1189
const adb = await this . getAdb ( ) ;
1172
1190
1191
+ // Use adjusted coordinates
1192
+ const { x : adjustedX , y : adjustedY } = this . adjustCoordinates ( x , y ) ;
1173
1193
await adb . shell (
1174
- `input${ this . getDisplayArg ( ) } swipe ${ x } ${ y } ${ x } ${ y } 150` ,
1194
+ `input${ this . getDisplayArg ( ) } swipe ${ adjustedX } ${ adjustedY } ${ adjustedX } ${ adjustedY } 150` ,
1175
1195
) ;
1176
1196
}
1177
1197
1178
1198
async mouseDoubleClick ( x : number , y : number ) : Promise < void > {
1179
1199
const adb = await this . getAdb ( ) ;
1200
+ const { x : adjustedX , y : adjustedY } = this . adjustCoordinates ( x , y ) ;
1180
1201
1181
1202
// Use input tap for double-click as it generates proper touch events
1182
1203
// that Android can recognize as a double-click gesture
1183
- const tapCommand = `input${ this . getDisplayArg ( ) } tap ${ x } ${ y } ` ;
1204
+ const tapCommand = `input${ this . getDisplayArg ( ) } tap ${ adjustedX } ${ adjustedY } ` ;
1184
1205
await adb . shell ( tapCommand ) ;
1185
1206
// Short delay between taps for double-click recognition
1186
1207
await sleep ( 50 ) ;
@@ -1200,11 +1221,15 @@ ${Object.keys(size)
1200
1221
) : Promise < void > {
1201
1222
const adb = await this . getAdb ( ) ;
1202
1223
1224
+ // Use adjusted coordinates
1225
+ const { x : fromX , y : fromY } = this . adjustCoordinates ( from . x , from . y ) ;
1226
+ const { x : toX , y : toY } = this . adjustCoordinates ( to . x , to . y ) ;
1227
+
1203
1228
// Ensure duration has a default value
1204
1229
const swipeDuration = duration ?? defaultNormalScrollDuration ;
1205
1230
1206
1231
await adb . shell (
1207
- `input${ this . getDisplayArg ( ) } swipe ${ from . x } ${ from . y } ${ to . x } ${ to . y } ${ swipeDuration } ` ,
1232
+ `input${ this . getDisplayArg ( ) } swipe ${ fromX } ${ fromY } ${ toX } ${ toY } ${ swipeDuration } ` ,
1208
1233
) ;
1209
1234
}
1210
1235
@@ -1244,12 +1269,22 @@ ${Object.keys(size)
1244
1269
const endX = startX - deltaX ;
1245
1270
const endY = startY - deltaY ;
1246
1271
1272
+ // Adjust coordinates to fit device ratio
1273
+ const { x : adjustedStartX , y : adjustedStartY } = this . adjustCoordinates (
1274
+ startX ,
1275
+ startY ,
1276
+ ) ;
1277
+ const { x : adjustedEndX , y : adjustedEndY } = this . adjustCoordinates (
1278
+ endX ,
1279
+ endY ,
1280
+ ) ;
1281
+
1247
1282
const adb = await this . getAdb ( ) ;
1248
1283
const swipeDuration = duration ?? defaultNormalScrollDuration ;
1249
1284
1250
1285
// Execute the swipe operation
1251
1286
await adb . shell (
1252
- `input${ this . getDisplayArg ( ) } swipe ${ startX } ${ startY } ${ endX } ${ endY } ${ swipeDuration } ` ,
1287
+ `input${ this . getDisplayArg ( ) } swipe ${ adjustedStartX } ${ adjustedStartY } ${ adjustedEndX } ${ adjustedEndY } ${ swipeDuration } ` ,
1253
1288
) ;
1254
1289
}
1255
1290
@@ -1290,8 +1325,10 @@ ${Object.keys(size)
1290
1325
async longPress ( x : number , y : number , duration = 1000 ) : Promise < void > {
1291
1326
const adb = await this . getAdb ( ) ;
1292
1327
1328
+ // Use adjusted coordinates
1329
+ const { x : adjustedX , y : adjustedY } = this . adjustCoordinates ( x , y ) ;
1293
1330
await adb . shell (
1294
- `input${ this . getDisplayArg ( ) } swipe ${ x } ${ y } ${ x } ${ y } ${ duration } ` ,
1331
+ `input${ this . getDisplayArg ( ) } swipe ${ adjustedX } ${ adjustedY } ${ adjustedX } ${ adjustedY } ${ duration } ` ,
1295
1332
) ;
1296
1333
}
1297
1334
@@ -1323,9 +1360,13 @@ ${Object.keys(size)
1323
1360
) : Promise < void > {
1324
1361
const adb = await this . getAdb ( ) ;
1325
1362
1363
+ // Use adjusted coordinates
1364
+ const { x : fromX , y : fromY } = this . adjustCoordinates ( from . x , from . y ) ;
1365
+ const { x : toX , y : toY } = this . adjustCoordinates ( to . x , to . y ) ;
1366
+
1326
1367
// Use the specified duration for better pull gesture recognition
1327
1368
await adb . shell (
1328
- `input${ this . getDisplayArg ( ) } swipe ${ from . x } ${ from . y } ${ to . x } ${ to . y } ${ duration } ` ,
1369
+ `input${ this . getDisplayArg ( ) } swipe ${ fromX } ${ fromY } ${ toX } ${ toY } ${ duration } ` ,
1329
1370
) ;
1330
1371
}
1331
1372
0 commit comments