@@ -5,7 +5,9 @@ import { AppError } from '../utils/errors.ts';
55import { runCmd } from '../utils/exec.ts' ;
66import {
77 assertAndroidPackageArgSafe ,
8+ readTrackedAndroidLogcatPid ,
89 readRecentAndroidLogcatForPackage ,
10+ resolveAndroidPid ,
911 startAndroidAppLog ,
1012} from './app-log-android.ts' ;
1113import {
@@ -14,7 +16,7 @@ import {
1416 startIosSimulatorAppLog ,
1517 startMacOsAppLog ,
1618} from './app-log-ios.ts' ;
17- import type { AppLogResult , AppLogState } from './app-log-process.ts' ;
19+ import { APP_LOG_PID_FILENAME , type AppLogResult , type AppLogState } from './app-log-process.ts' ;
1820import { waitForChildExit } from './app-log-stream.ts' ;
1921import {
2022 mergeNetworkDumps ,
@@ -49,6 +51,11 @@ export type SessionNetworkCapture = {
4951 notes : string [ ] ;
5052} ;
5153
54+ type AndroidNetworkRecoveryContext = {
55+ reason : 'inactive' | 'stale-active' ;
56+ trackedPid ?: string ;
57+ } ;
58+
5259type IosSimulatorNetworkRecovery = {
5360 dump : NetworkDump ;
5461 recoveredLineCount : number ;
@@ -171,12 +178,13 @@ export async function readSessionNetworkCapture(params: {
171178 } ) ;
172179 const notes : string [ ] = [ ] ;
173180
174- const canRecoverAndroidLogcat =
175- device . platform === 'android' &&
176- appLogState !== undefined &&
177- appLogState !== 'active' &&
178- Boolean ( appBundleId ) ;
179- if ( canRecoverAndroidLogcat ) {
181+ const androidRecovery = await resolveAndroidNetworkRecoveryContext ( {
182+ device,
183+ appBundleId,
184+ appLogPath,
185+ appLogState,
186+ } ) ;
187+ if ( androidRecovery ) {
180188 const recovered = await readRecentAndroidLogcatForPackage ( device . id , appBundleId as string ) ;
181189 if ( recovered ) {
182190 const recoveredDump = readRecentNetworkTrafficFromText ( recovered . text , {
@@ -189,9 +197,7 @@ export async function readSessionNetworkCapture(params: {
189197 } ) ;
190198 if ( recoveredDump . entries . length > 0 ) {
191199 dump = mergeNetworkDumps ( recoveredDump , dump , maxEntries ) ;
192- notes . push (
193- `Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${ recovered . recoveredPids . join ( ', ' ) } .` ,
194- ) ;
200+ notes . push ( buildAndroidRecoveryNote ( androidRecovery , recovered . recoveredPids ) ) ;
195201 }
196202 }
197203 }
@@ -248,6 +254,46 @@ export async function readSessionNetworkCapture(params: {
248254 return { backend, dump, notes } ;
249255}
250256
257+ async function resolveAndroidNetworkRecoveryContext ( params : {
258+ device : DeviceInfo ;
259+ appBundleId ?: string ;
260+ appLogPath : string ;
261+ appLogState ?: AppLogState ;
262+ } ) : Promise < AndroidNetworkRecoveryContext | null > {
263+ const { device, appBundleId, appLogPath, appLogState } = params ;
264+ if ( device . platform !== 'android' || ! appBundleId ) {
265+ return null ;
266+ }
267+ if ( appLogState !== undefined && appLogState !== 'active' ) {
268+ return { reason : 'inactive' } ;
269+ }
270+ if ( appLogState !== 'active' ) {
271+ return null ;
272+ }
273+
274+ const trackedPid = readTrackedAndroidLogcatPid (
275+ path . join ( path . dirname ( appLogPath ) , APP_LOG_PID_FILENAME ) ,
276+ ) ;
277+ if ( ! trackedPid ) {
278+ return null ;
279+ }
280+ const currentPid = await resolveAndroidPid ( device . id , appBundleId ) ;
281+ if ( ! currentPid || currentPid === trackedPid ) {
282+ return null ;
283+ }
284+ return { reason : 'stale-active' , trackedPid } ;
285+ }
286+
287+ function buildAndroidRecoveryNote (
288+ context : AndroidNetworkRecoveryContext ,
289+ recoveredPids : string [ ] ,
290+ ) : string {
291+ if ( context . reason === 'stale-active' ) {
292+ return `Session app log stream was still bound to prior Android PID ${ context . trackedPid } . Recovered recent Android HTTP entries from adb logcat for PID set ${ recoveredPids . join ( ', ' ) } .` ;
293+ }
294+ return `Session app log stream was inactive. Recovered recent Android HTTP entries from adb logcat for PID set ${ recoveredPids . join ( ', ' ) } .` ;
295+ }
296+
251297export async function startAppLog (
252298 device : DeviceInfo ,
253299 appBundleId : string ,
0 commit comments