Skip to content

Commit 22324a1

Browse files
committed
refactor: consolidate android gesture backend selection
1 parent 7ab9998 commit 22324a1

3 files changed

Lines changed: 54 additions & 90 deletions

File tree

src/platforms/android/__tests__/multitouch-helper.test.ts

Lines changed: 1 addition & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,10 @@ import { ANDROID_EMULATOR } from '../../../__tests__/test-utils/index.ts';
88
import {
99
ensureAndroidMultiTouchHelper,
1010
parseAndroidMultiTouchHelperOutput,
11-
pinchAndroid,
1211
resetAndroidMultiTouchHelperInstallCache,
1312
rotateGestureAndroid,
1413
runAndroidMultiTouchHelperGesture,
1514
swipeGestureAndroid,
16-
transformGestureAndroid,
1715
} from '../multitouch-helper.ts';
1816
import {
1917
withAndroidAdbProvider,
@@ -109,9 +107,7 @@ test('runAndroidMultiTouchHelperGesture encodes one-finger swipe payloads', asyn
109107
capturedPayload = JSON.parse(Buffer.from(args[6]!, 'base64').toString('utf8'));
110108
return {
111109
exitCode: 0,
112-
stdout: [resultRecord({ ok: 'true', kind: 'swipe' }), 'INSTRUMENTATION_CODE: 0'].join(
113-
'\n',
114-
),
110+
stdout: [resultRecord({ ok: 'true', kind: 'swipe' }), 'INSTRUMENTATION_CODE: 0'].join('\n'),
115111
stderr: '',
116112
};
117113
},
@@ -166,66 +162,6 @@ test('runAndroidMultiTouchHelperGesture preserves helper failure messages', asyn
166162
);
167163
});
168164

169-
test('swipeGestureAndroid and multi-touch gestures prefer provider-native touch injection', async () => {
170-
const calls: unknown[] = [];
171-
await withAndroidAdbProvider(
172-
{
173-
exec: async () => {
174-
throw new Error('adb should not run when native touch is available');
175-
},
176-
touch: async (request) => {
177-
calls.push(request);
178-
return { backendDetail: 'native' };
179-
},
180-
},
181-
{ serial: ANDROID_EMULATOR.id },
182-
async () => {
183-
const swipe = await swipeGestureAndroid(ANDROID_EMULATOR, {
184-
x1: 340,
185-
y1: 400,
186-
x2: 60,
187-
y2: 400,
188-
durationMs: 300,
189-
});
190-
const pinch = await pinchAndroid(ANDROID_EMULATOR, { scale: 2, x: 100, y: 200 });
191-
const rotate = await rotateGestureAndroid(ANDROID_EMULATOR, {
192-
degrees: -215,
193-
x: 100,
194-
y: 200,
195-
});
196-
const transform = await transformGestureAndroid(ANDROID_EMULATOR, {
197-
x: 100,
198-
y: 200,
199-
dx: 30,
200-
dy: -20,
201-
scale: 1.5,
202-
degrees: 35,
203-
});
204-
205-
assert.equal(swipe?.backend, 'provider-native-touch');
206-
assert.equal(pinch.backend, 'provider-native-touch');
207-
assert.equal(rotate.backend, 'provider-native-touch');
208-
assert.equal(transform.backend, 'provider-native-touch');
209-
},
210-
);
211-
212-
assert.deepEqual(calls, [
213-
{ kind: 'swipe', x1: 340, y1: 400, x2: 60, y2: 400, durationMs: 300 },
214-
{ kind: 'pinch', x: 100, y: 200, scale: 2, durationMs: undefined },
215-
{ kind: 'rotate', x: 100, y: 200, degrees: -215, durationMs: undefined },
216-
{
217-
kind: 'transform',
218-
x: 100,
219-
y: 200,
220-
dx: 30,
221-
dy: -20,
222-
scale: 1.5,
223-
degrees: 35,
224-
durationMs: undefined,
225-
},
226-
]);
227-
});
228-
229165
test('swipeGestureAndroid falls back to adb input swipe when helper path is unavailable', async () => {
230166
const adbCalls: string[][] = [];
231167
const result = await withAndroidAdbProvider(

src/platforms/android/multitouch-helper.ts

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -120,27 +120,28 @@ export async function swipeGestureAndroid(
120120
device: DeviceInfo,
121121
options: AndroidSwipeGestureOptions,
122122
): Promise<Record<string, unknown> | void> {
123-
const providerTouch = resolveAndroidTouchInjector(device);
124-
if (providerTouch) {
125-
return {
126-
backend: 'provider-native-touch',
127-
...((await providerTouch({ kind: 'swipe', ...options })) ?? {}),
128-
};
129-
}
130-
131-
try {
132-
return await runAndroidMultiTouchGesture(device, { kind: 'swipe', ...options });
133-
} catch (error) {
134-
emitDiagnostic({
135-
level: 'warn',
136-
phase: 'android_swipe_helper_fallback',
137-
data: {
138-
error: normalizeError(error).message,
139-
},
140-
});
141-
await swipeAndroid(device, options.x1, options.y1, options.x2, options.y2, options.durationMs);
142-
return { backend: 'adb-input-swipe-fallback' };
143-
}
123+
return await performAndroidTouchGestureWithFallback(
124+
device,
125+
{ kind: 'swipe', ...options },
126+
async (error) => {
127+
emitDiagnostic({
128+
level: 'warn',
129+
phase: 'android_swipe_helper_fallback',
130+
data: {
131+
error: normalizeError(error).message,
132+
},
133+
});
134+
await swipeAndroid(
135+
device,
136+
options.x1,
137+
options.y1,
138+
options.x2,
139+
options.y2,
140+
options.durationMs,
141+
);
142+
return { backend: 'adb-input-swipe-fallback' };
143+
},
144+
);
144145
}
145146

146147
export async function pinchAndroid(
@@ -151,7 +152,7 @@ export async function pinchAndroid(
151152
throw new AppError('INVALID_ARGS', 'gesture pinch requires scale > 0');
152153
}
153154
const center = await resolveGestureCenter(device, options.x, options.y);
154-
return await runAndroidMultiTouchGesture(device, {
155+
return await performAndroidTouchGesture(device, {
155156
kind: 'pinch',
156157
x: center.x,
157158
y: center.y,
@@ -175,7 +176,7 @@ export async function rotateGestureAndroid(
175176
}
176177
const center = await resolveGestureCenter(device, options.x, options.y);
177178
const degrees = options.degrees;
178-
return await runAndroidMultiTouchGesture(device, {
179+
return await performAndroidTouchGesture(device, {
179180
kind: 'rotate',
180181
x: center.x,
181182
y: center.y,
@@ -197,7 +198,7 @@ export async function transformGestureAndroid(
197198
if (![options.x, options.y, options.dx, options.dy].every(Number.isFinite)) {
198199
throw new AppError('INVALID_ARGS', 'gesture transform requires finite x y dx dy');
199200
}
200-
return await runAndroidMultiTouchGesture(device, {
201+
return await performAndroidTouchGesture(device, {
201202
kind: 'transform',
202203
x: options.x,
203204
y: options.y,
@@ -219,7 +220,19 @@ async function resolveGestureCenter(
219220
return { x: Math.round(size.width / 2), y: Math.round(size.height / 2) };
220221
}
221222

222-
async function runAndroidMultiTouchGesture(
223+
async function performAndroidTouchGestureWithFallback(
224+
device: DeviceInfo,
225+
request: AndroidTouchGestureRequest,
226+
fallback: (error: unknown) => Promise<Record<string, unknown> | void>,
227+
): Promise<Record<string, unknown> | void> {
228+
try {
229+
return await performAndroidTouchGesture(device, request);
230+
} catch (error) {
231+
return await fallback(error);
232+
}
233+
}
234+
235+
async function performAndroidTouchGesture(
223236
device: DeviceInfo,
224237
request: AndroidTouchGestureRequest,
225238
): Promise<Record<string, unknown>> {
@@ -229,6 +242,13 @@ async function runAndroidMultiTouchGesture(
229242
return { backend: 'provider-native-touch', ...result };
230243
}
231244

245+
return await runAndroidMultiTouchHelperGestureForDevice(device, request);
246+
}
247+
248+
async function runAndroidMultiTouchHelperGestureForDevice(
249+
device: DeviceInfo,
250+
request: AndroidTouchGestureRequest,
251+
): Promise<Record<string, unknown>> {
232252
const adb = resolveAndroidAdbExecutor(device);
233253
const artifact = await resolveAndroidMultiTouchHelperArtifact();
234254
const adbProvider = resolveAndroidAdbProvider(device);

test/integration/provider-scenarios/android-lifecycle.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,13 @@ test('Provider-backed integration Android touch provider handles multi-touch ges
8585
const client = world.daemon.client();
8686
await client.apps.open({ app: 'settings', ...world.selection });
8787

88+
await client.interactions.swipe({
89+
from: { x: 340, y: 400 },
90+
to: { x: 60, y: 400 },
91+
durationMs: 300,
92+
...world.selection,
93+
});
94+
8895
const pinch = await client.interactions.pinch({
8996
scale: 2,
9097
x: 195,
@@ -118,6 +125,7 @@ test('Provider-backed integration Android touch provider handles multi-touch ges
118125
assert.equal(transform.backend, 'provider-native-touch');
119126

120127
assert.deepEqual(world.touchInjectionCalls, [
128+
{ kind: 'swipe', x1: 340, y1: 400, x2: 60, y2: 400, durationMs: 300 },
121129
{ kind: 'pinch', x: 195, y: 320, scale: 2, durationMs: undefined },
122130
{ kind: 'rotate', x: 195, y: 320, degrees: 145, durationMs: undefined },
123131
{

0 commit comments

Comments
 (0)