Skip to content

Commit 4046d83

Browse files
committed
fix: satisfy Android ANR fallow audit
1 parent 1656494 commit 4046d83

3 files changed

Lines changed: 32 additions & 17 deletions

File tree

src/daemon/handlers/interaction.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { DaemonResponse } from '../types.ts';
1+
import type { DaemonResponse, SessionState } from '../types.ts';
22
import type { InteractionHandlerParams } from './interaction-common.ts';
33
import { handleTouchInteractionCommands } from './interaction-touch.ts';
44
import { captureSnapshotForSession } from './interaction-snapshot.ts';
@@ -48,19 +48,37 @@ async function dispatchTypeViaRuntime(
4848
captureSnapshotForSession: typeof captureSnapshotForSession;
4949
},
5050
): Promise<DaemonResponse> {
51-
const { req, sessionName, sessionStore } = params;
51+
const { sessionName, sessionStore } = params;
5252
const session = sessionStore.get(sessionName);
5353
if (!session) return errorResponse('SESSION_NOT_FOUND', 'No active session. Run open first.');
5454
if (!isCommandSupportedOnDevice(typeCommandDefinition.name, session.device)) {
5555
return errorResponse('UNSUPPORTED_OPERATION', 'type is not supported on this device');
5656
}
57+
const recordingRecoveryResponse = await recoverAndroidRecordingDialogForType(session);
58+
if (recordingRecoveryResponse) return recordingRecoveryResponse;
59+
60+
return await runTypeTextViaRuntime(params, session);
61+
}
62+
63+
async function recoverAndroidRecordingDialogForType(
64+
session: SessionState,
65+
): Promise<DaemonResponse | null> {
5766
if (session.device.platform === 'android' && session.recording) {
5867
const androidRecoveryResult = await recoverAndroidBlockingSystemDialog({ session });
5968
if (androidRecoveryResult === 'failed') {
6069
return errorResponse('COMMAND_FAILED', 'Android system dialog blocked the recording session');
6170
}
6271
}
72+
return null;
73+
}
6374

75+
async function runTypeTextViaRuntime(
76+
params: InteractionHandlerParams & {
77+
captureSnapshotForSession: typeof captureSnapshotForSession;
78+
},
79+
session: SessionState,
80+
): Promise<DaemonResponse> {
81+
const { req, sessionName, sessionStore } = params;
6482
const text = (req.positionals ?? []).join(' ');
6583
const runtime = createInteractionRuntime(params);
6684
const actionStartedAt = Date.now();

src/platforms/android/app-lifecycle.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
} from './app-parsers.ts';
2828

2929
export {
30-
parseAndroidBlockingDialogFocus,
3130
parseAndroidForegroundApp,
3231
parseAndroidLaunchablePackages,
3332
parseAndroidUserInstalledPackages,

src/platforms/android/app-parsers.ts

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,21 +40,19 @@ export function parseAndroidUserInstalledPackages(stdout: string): string[] {
4040
}
4141

4242
export function parseAndroidForegroundApp(text: string): AndroidForegroundApp | null {
43-
const lines = text.split('\n');
44-
45-
for (const marker of ANDROID_FOCUS_MARKERS) {
46-
for (const line of lines) {
47-
const markerIndex = line.indexOf(marker);
48-
if (markerIndex === -1) continue;
49-
const segment = line.slice(markerIndex + marker.length);
50-
const parsed = parseAndroidComponentFromSegment(segment);
51-
if (parsed) return parsed;
52-
}
53-
}
54-
return null;
43+
return parseAndroidFocusSegment(text, (segment) => parseAndroidComponentFromSegment(segment));
5544
}
5645

5746
export function parseAndroidBlockingDialogFocus(text: string): AndroidBlockingDialogFocus | null {
47+
return parseAndroidFocusSegment(text, (segment, raw) =>
48+
parseAndroidBlockingDialogFromSegment(segment, raw),
49+
);
50+
}
51+
52+
function parseAndroidFocusSegment<T>(
53+
text: string,
54+
parse: (segment: string, raw: string) => T | null,
55+
): T | null {
5856
const lines = text.split('\n');
5957

6058
for (const marker of ANDROID_FOCUS_MARKERS) {
@@ -63,8 +61,8 @@ export function parseAndroidBlockingDialogFocus(text: string): AndroidBlockingDi
6361
if (markerIndex === -1) continue;
6462
const raw = line.trim();
6563
const segment = line.slice(markerIndex + marker.length);
66-
const focus = parseAndroidBlockingDialogFromSegment(segment, raw);
67-
if (focus) return focus;
64+
const parsed = parse(segment, raw);
65+
if (parsed) return parsed;
6866
}
6967
}
7068
return null;

0 commit comments

Comments
 (0)