@@ -19,7 +19,9 @@ import {
1919 hasCertInstalled ,
2020 bringToFront ,
2121 setChromeFlags ,
22- startActivity
22+ startActivity ,
23+ createPersistentReverseTunnel ,
24+ closeReverseTunnel
2325} from './adb-commands' ;
2426import { streamLatestApk , clearAllApks } from './fetch-apk' ;
2527import { parseCert , getCertificateFingerprint , getCertificateSubjectHash } from '../../certificates' ;
@@ -108,7 +110,8 @@ export class AndroidAdbInterceptor implements Interceptor {
108110 } ;
109111 const intentData = urlSafeBase64 ( JSON . stringify ( setupParams ) ) ;
110112
111- await deviceClient . reverse ( 'tcp:' + proxyPort , 'tcp:' + proxyPort ) . catch ( ( ) => { } ) ;
113+ await createPersistentReverseTunnel ( deviceClient , proxyPort , proxyPort )
114+ . catch ( ( ) => { } ) ; // If we can't tunnel that's OK - we'll use wifi/etc instead
112115
113116 // Use ADB to launch the app with the proxy details
114117 await startActivity ( deviceClient , {
@@ -118,41 +121,8 @@ export class AndroidAdbInterceptor implements Interceptor {
118121 } ) ;
119122
120123 this . deviceProxyMapping [ proxyPort ] = this . deviceProxyMapping [ proxyPort ] || [ ] ;
121-
122124 if ( ! this . deviceProxyMapping [ proxyPort ] . includes ( options . deviceId ) ) {
123125 this . deviceProxyMapping [ proxyPort ] . push ( options . deviceId ) ;
124-
125- let tunnelConnectFailures = 0 ;
126-
127- // The reverse tunnel can break when connecting/disconnecting from the VPN. This is a problem! It can
128- // also break in other cases, e.g. when ADB is restarted for some reason. To handle this, we constantly
129- // reinforce the tunnel while HTTP Toolkit is running & the device is connected.
130- const tunnelCheckInterval = setInterval ( async ( ) => {
131- if ( this . deviceProxyMapping [ proxyPort ] . includes ( options . deviceId ) ) {
132- try {
133- await deviceClient . reverse ( 'tcp:' + proxyPort , 'tcp:' + proxyPort )
134- tunnelConnectFailures = 0 ;
135- } catch ( e ) {
136- tunnelConnectFailures += 1 ;
137- console . log ( `${ options . deviceId } ADB tunnel failed` ,
138- isErrorLike ( e ) ? e . message : e
139- ) ;
140-
141- if ( tunnelConnectFailures >= 5 ) {
142- // After 10 seconds disconnected, give up
143- console . log ( `${ options . deviceId } disconnected, dropping the ADB tunnel` ) ;
144- this . deviceProxyMapping [ proxyPort ] = this . deviceProxyMapping [ proxyPort ]
145- . filter ( id => id !== options . deviceId ) ;
146- clearInterval ( tunnelCheckInterval ) ;
147- }
148- }
149- } else {
150- // Deactivation at shutdown will clear the proxy data, and so clear this interval
151- // will automatically shut down.
152- clearInterval ( tunnelCheckInterval ) ;
153- }
154- } , 2000 ) ;
155- tunnelCheckInterval . unref ( ) ; // Don't let this block shutdown
156126 }
157127 }
158128
@@ -174,6 +144,8 @@ export class AndroidAdbInterceptor implements Interceptor {
174144 wait : true ,
175145 action : 'tech.httptoolkit.android.DEACTIVATE'
176146 } ) ;
147+
148+ closeReverseTunnel ( deviceClient , port , port ) ;
177149 } )
178150 ) ;
179151 }
0 commit comments