@@ -120,15 +120,15 @@ export async function acquireAndroidSnapshotHelperSession(
120120 if ( ! isAndroidSnapshotHelperSessionEnabled ( ) || ! options . adbProvider ?. spawn ) {
121121 return undefined ;
122122 }
123- const resolved = resolvePersistentSessionCaptureOptions (
124- resolveAndroidSnapshotHelperCaptureOptions ( options ) ,
125- ) ;
123+ const callerResolved = resolveAndroidSnapshotHelperCaptureOptions ( options ) ;
124+ const resolved = resolvePersistentSessionCaptureOptions ( callerResolved ) ;
126125 const identity = createSessionIdentity ( deviceKey , resolved , options ) ;
127126 const session = await resolveAndroidSnapshotHelperSession ( {
128127 deviceKey,
129128 identity,
130129 options,
131130 resolved,
131+ startBudgetMs : resolveAndroidSnapshotHelperStartBudgetMs ( callerResolved . commandTimeoutMs ) ,
132132 } ) ;
133133 return session ? { session, resolved, deviceKey } : undefined ;
134134}
@@ -148,6 +148,7 @@ async function resolveAndroidSnapshotHelperSession(params: {
148148 identity : string ;
149149 options : AndroidSnapshotHelperCaptureOptions ;
150150 resolved : AndroidSnapshotHelperResolvedCaptureOptions ;
151+ startBudgetMs : number ;
151152} ) : Promise < AndroidSnapshotHelperSession | undefined > {
152153 if ( isAndroidSnapshotHelperStartBackedOff ( params . identity ) ) return undefined ;
153154 await retireUnusableAndroidSnapshotHelperSession ( params . deviceKey , params . identity ) ;
@@ -178,6 +179,7 @@ async function tryStartAndroidSnapshotHelperSession(params: {
178179 identity : string ;
179180 options : AndroidSnapshotHelperCaptureOptions ;
180181 resolved : AndroidSnapshotHelperResolvedCaptureOptions ;
182+ startBudgetMs : number ;
181183} ) : Promise < AndroidSnapshotHelperSession | undefined > {
182184 const startedAtMs = Date . now ( ) ;
183185 try {
@@ -240,6 +242,7 @@ async function startAndroidSnapshotHelperSession(params: {
240242 identity : string ;
241243 options : AndroidSnapshotHelperCaptureOptions ;
242244 resolved : AndroidSnapshotHelperResolvedCaptureOptions ;
245+ startBudgetMs : number ;
243246} ) : Promise < AndroidSnapshotHelperSession > {
244247 const port = await allocateAndroidSnapshotHelperSessionPort ( ) ;
245248 await params . options . adb ( [ 'forward' , `tcp:${ port } ` , `tcp:${ port } ` ] , {
@@ -278,12 +281,12 @@ async function startAndroidSnapshotHelperSession(params: {
278281 capturedCount : 0 ,
279282 } ;
280283 try {
281- // Starting the session gets the budget the caller already allowed one helper command , which is
282- // how `--timeout` reaches it. A fixed guess below that pushed a slow device out of the persistent
283- // path while the one-shot transport it fell back to had room for the same start .
284+ // A helper that announces itself late is a slow `am instrument` , which the one-shot transport it
285+ // falls back to pays too. The start gets its share of the caller's command budget instead of a
286+ // fixed guess, so `--timeout` decides whether the persistent path is affordable at all .
284287 await waitForAndroidSnapshotHelperSessionReady (
285288 childProcess ,
286- params . resolved . commandTimeoutMs ,
289+ params . startBudgetMs ,
287290 params . options . signal ,
288291 ) ;
289292 sessions . set ( params . deviceKey , session ) ;
@@ -369,6 +372,22 @@ function resolvePersistentSessionCaptureOptions(
369372 } ;
370373}
371374
375+ /**
376+ * What a start gets out of the budget the caller allowed one helper command: half of it, so a helper
377+ * that announces itself later than a session capture takes is not pushed off the persistent path by
378+ * a capture-sized guess, while the one-shot transport that answers a failed start keeps the other
379+ * half. Never less than one session command is worth, never more than the caller allowed.
380+ */
381+ export function resolveAndroidSnapshotHelperStartBudgetMs ( commandTimeoutMs : number ) : number {
382+ return Math . min (
383+ commandTimeoutMs ,
384+ Math . max (
385+ Math . floor ( commandTimeoutMs / 2 ) ,
386+ SESSION_CAPTURE_TIMEOUT_MS + SESSION_REQUEST_OVERHEAD_MS ,
387+ ) ,
388+ ) ;
389+ }
390+
372391function isAndroidSnapshotHelperSessionEnabled ( ) : boolean {
373392 const value = requireAndroidAdbHost ( ) . environment . AGENT_DEVICE_ANDROID_SNAPSHOT_HELPER_SESSION ;
374393 return value === undefined || ! / ^ ( 0 | f a l s e | n o | o f f ) $ / i. test ( value ) ;
0 commit comments