@@ -181,18 +181,72 @@ const getFridaStream = (hostId: string, deviceClient: DeviceClient) =>
181181 } ) ;
182182 } ) ;
183183
184- export async function getAndroidFridaTargets ( adbClient : AdbClient , hostId : string ) {
185- const deviceClient = adbClient . getDevice ( hostId ) ;
184+ const fridaSessionCache : Record < string , {
185+ fridaSession : FridaJs . FridaSession ,
186+ cleanup : ( ) => void ,
187+ timeout : NodeJS . Timeout
188+ } > = { } ;
189+
190+ const FRIDA_SESSION_IDLE_TIMEOUT = 30_000 ;
191+
192+ function clearFridaSessionCache ( hostId : string ) {
193+ const cached = fridaSessionCache [ hostId ] ;
194+ if ( cached ) {
195+ clearTimeout ( cached . timeout ) ;
196+ cached . cleanup ( ) ;
197+ delete fridaSessionCache [ hostId ] ;
198+ }
199+ }
200+
201+ async function getOrCreateFridaSession ( hostId : string , deviceClient : DeviceClient ) {
202+ let cached = fridaSessionCache [ hostId ] ;
203+ if ( cached ) {
204+ clearTimeout ( cached . timeout ) ;
205+ cached . timeout = setTimeout ( ( ) => clearFridaSessionCache ( hostId ) , FRIDA_SESSION_IDLE_TIMEOUT ) ;
206+ return { fridaSession : cached . fridaSession , wasCached : true } ;
207+ }
186208
187209 const fridaStream = await getFridaStream ( hostId , deviceClient ) ;
210+ const fridaSession = await FridaJs . connect ( { stream : fridaStream } ) ;
188211
189- const fridaSession = await FridaJs . connect ( {
190- stream : fridaStream
191- } ) ;
212+ const timeout = setTimeout ( ( ) => clearFridaSessionCache ( hostId ) , FRIDA_SESSION_IDLE_TIMEOUT ) ;
213+ const cleanup = ( ) => fridaSession . disconnect ( )
214+ . catch ( ( ) => { } )
215+ . finally ( ( ) => fridaStream . destroy ( ) ) ;
216+
217+ fridaSessionCache [ hostId ] = {
218+ fridaSession,
219+ cleanup,
220+ timeout
221+ } ;
192222
193- const apps = await fridaSession . enumerateApplications ( ) ;
194- fridaSession . disconnect ( ) . catch ( ( ) => { } ) ;
195- return apps ;
223+ fridaStream . on ( 'error' , cleanup ) ;
224+ return { fridaSession, wasCached : false } ;
225+ }
226+
227+ export async function getAndroidFridaTargets ( adbClient : AdbClient , hostId : string ) : Promise < Array < {
228+ pid : number | null ;
229+ id : string ;
230+ name : string ;
231+ } > > {
232+ const deviceClient = adbClient . getDevice ( hostId ) ;
233+
234+ let fridaSession : FridaJs . FridaSession ;
235+ let wasCached : boolean = false ;
236+
237+ try {
238+ ( { fridaSession, wasCached } = await getOrCreateFridaSession ( hostId , deviceClient ) ) ;
239+ const apps = await fridaSession . enumerateApplications ( ) ;
240+ return apps ;
241+ } catch ( e ) {
242+ clearFridaSessionCache ( hostId ) ;
243+ if ( wasCached ) {
244+ // When a cached session fails, we retry with a fresh one:
245+ return getAndroidFridaTargets ( adbClient , hostId ) ;
246+ } else {
247+ throw e ;
248+ }
249+ }
196250}
197251
198252// Various ports which we know that certain apps use for non-HTTP traffic that we
0 commit comments