Skip to content

Commit 45e3de9

Browse files
committed
Replace manual connect with reconnect
1 parent ffc30cb commit 45e3de9

File tree

2 files changed

+46
-16
lines changed

2 files changed

+46
-16
lines changed

app/src/main/java/tech/httptoolkit/android/MainActivity.kt

Lines changed: 45 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ private fun getCertificateFingerprint(cert: X509Certificate): String {
6262
class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
6363

6464
private val TAG = MainActivity::class.simpleName
65-
private var app: HttpToolkitApplication? = null
65+
private lateinit var app: HttpToolkitApplication
6666

6767
private var localBroadcastManager: LocalBroadcastManager? = null
6868
private val broadcastReceiver = object : BroadcastReceiver() {
@@ -86,16 +86,14 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
8686
override fun onCreate(savedInstanceState: Bundle?) {
8787
super.onCreate(savedInstanceState)
8888

89-
setContentView(R.layout.main_layout)
90-
updateUi()
91-
9289
localBroadcastManager = LocalBroadcastManager.getInstance(this)
9390
localBroadcastManager!!.registerReceiver(broadcastReceiver, IntentFilter().apply {
9491
addAction(VPN_STARTED_BROADCAST)
9592
addAction(VPN_STOPPED_BROADCAST)
9693
})
9794

9895
app = this.application as HttpToolkitApplication
96+
setContentView(R.layout.main_layout)
9997
updateUi()
10098

10199
Log.i(TAG, "Main activity created")
@@ -107,7 +105,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
107105
// If not, check if this is a post-install run, and if so configure automatically
108106
// using the install referrer
109107
launch {
110-
val firstRunParams = app!!.popFirstRunParams()
108+
val firstRunParams = app.popFirstRunParams()
111109
if (
112110
firstRunParams != null &&
113111
firstRunParams.startsWith("https://android.httptoolkit.tech/connect/")
@@ -121,13 +119,13 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
121119
override fun onResume() {
122120
super.onResume()
123121
Log.d(TAG, "onResume")
124-
app!!.trackScreen("Main")
122+
app.trackScreen("Main")
125123
}
126124

127125
override fun onPause() {
128126
super.onPause()
129127
Log.d(TAG, "onPause")
130-
app!!.clearScreen()
128+
app.clearScreen()
131129
}
132130

133131
override fun onDestroy() {
@@ -144,9 +142,9 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
144142
return
145143
}
146144

147-
app!!.trackEvent("Setup", "action-view")
145+
app.trackEvent("Setup", "action-view")
148146

149-
if (app!!.lastProxy != null && isVpnConfigured()) {
147+
if (app.lastProxy != null && isVpnConfigured()) {
150148
Log.i(TAG, "Showing prompt for ACTION_VIEW intent")
151149

152150
// If we were started from an intent (e.g. another barcode scanner/link), and we
@@ -190,7 +188,13 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
190188

191189
buttonContainer.visibility = View.VISIBLE
192190
buttonContainer.addView(primaryButton(R.string.scan_button, ::scanCode))
193-
buttonContainer.addView(secondaryButton(R.string.manual_button, { }))
191+
192+
val lastProxy = app.lastProxy
193+
if (lastProxy != null) {
194+
buttonContainer.addView(secondaryButton(R.string.reconnect_button) {
195+
launch { reconnect(lastProxy) }
196+
})
197+
}
194198
}
195199
MainState.CONNECTING -> {
196200
statusText.setText(R.string.connecting_status)
@@ -248,7 +252,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
248252
}
249253

250254
private fun scanCode() {
251-
app!!.trackEvent("Button", "scan-code")
255+
app.trackEvent("Button", "scan-code")
252256
startActivityForResult(Intent(this, ScanActivity::class.java), SCAN_REQUEST)
253257
}
254258

@@ -260,7 +264,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
260264

261265
withContext(Dispatchers.Main) { updateUi() }
262266

263-
app!!.trackEvent("Button", "start-vpn")
267+
app.trackEvent("Button", "start-vpn")
264268
val vpnIntent = VpnService.prepare(this)
265269
Log.i(TAG, if (vpnIntent != null) "got intent" else "no intent")
266270

@@ -296,12 +300,37 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
296300
mainState = MainState.DISCONNECTING
297301
updateUi()
298302

299-
app!!.trackEvent("Button", "stop-vpn")
303+
app.trackEvent("Button", "stop-vpn")
300304
startService(Intent(this, ProxyVpnService::class.java).apply {
301305
action = STOP_VPN_ACTION
302306
})
303307
}
304308

309+
private suspend fun reconnect(lastProxy: ProxyConfig) {
310+
try {
311+
// Revalidates the config, to ensure the server is available (and drop retries if not)
312+
val config = getProxyConfig(
313+
ProxyInfo(
314+
listOf(lastProxy.ip),
315+
lastProxy.port,
316+
getCertificateFingerprint(lastProxy.certificate as X509Certificate)
317+
)
318+
)
319+
connectToVpn(config)
320+
} catch (e: Exception) {
321+
app.lastProxy = null
322+
323+
Log.e(TAG, e.toString())
324+
e.printStackTrace()
325+
Sentry.capture(e)
326+
withContext(Dispatchers.Main) {
327+
app.trackEvent("Setup", "reconnect-failed")
328+
mainState = MainState.FAILED
329+
updateUi()
330+
}
331+
}
332+
}
333+
305334
private fun resetAfterFailure() {
306335
currentProxyConfig = null
307336
mainState = MainState.DISCONNECTED
@@ -381,7 +410,7 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
381410
e.printStackTrace()
382411
Sentry.capture(e)
383412
withContext(Dispatchers.Main) {
384-
app!!.trackEvent("Setup", "connect-failed")
413+
app.trackEvent("Setup", "connect-failed")
385414
mainState = MainState.FAILED
386415
updateUi()
387416
}
@@ -496,14 +525,14 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
496525

497526
private fun ensureCertificateTrusted(proxyConfig: ProxyConfig) {
498527
if (!isCertTrusted(proxyConfig)) {
499-
app!!.trackEvent("Setup", "installing-cert")
528+
app.trackEvent("Setup", "installing-cert")
500529
Log.i(TAG, "Certificate not trusted, prompting to install")
501530
val certInstallIntent = KeyChain.createInstallIntent()
502531
certInstallIntent.putExtra(EXTRA_NAME, "HTTP Toolkit CA")
503532
certInstallIntent.putExtra(EXTRA_CERTIFICATE, proxyConfig.certificate.encoded)
504533
startActivityForResult(certInstallIntent, INSTALL_CERT_REQUEST)
505534
} else {
506-
app!!.trackEvent("Setup", "existing-cert")
535+
app.trackEvent("Setup", "existing-cert")
507536
Log.i(TAG, "Certificate already trusted, continuing")
508537
onActivityResult(INSTALL_CERT_REQUEST, RESULT_OK, null)
509538
}

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
</string>
2525

2626
<string name="scan_button">Scan Code</string>
27+
<string name="reconnect_button">Reconnect</string>
2728
<string name="manual_button">Connect Manually</string>
2829
<string name="disconnect_button">Disconnect</string>
2930
<string name="docs_button">Read the Docs</string>

0 commit comments

Comments
 (0)