@@ -14,6 +14,7 @@ import android.provider.Settings
1414import android.security.KeyChain
1515import android.security.KeyChain.EXTRA_CERTIFICATE
1616import android.security.KeyChain.EXTRA_NAME
17+ import android.text.Html
1718import android.util.Log
1819import android.view.View
1920import android.widget.Button
@@ -552,6 +553,16 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
552553 // Then go back to the disconnected state:
553554 mainState = MainState .DISCONNECTED
554555 updateUi()
556+ } else if (
557+ requestCode == INSTALL_CERT_REQUEST &&
558+ Build .VERSION .SDK_INT >= Build .VERSION_CODES .Q // Required for promptToManuallyInstallCert
559+ ) {
560+ // Certificate install failed. Could be manual (failed to follow instructions) or automated
561+ // via prompt. We redo the manual step regardless: either (on modern Android) manual is
562+ // required so this is just reshowing the instructions, or it was automated but that's not
563+ // working for some reason, in which case manual setup is a best-effort fallback.
564+ app.trackEvent(" Setup" , " cert-install-failed" )
565+ launch { promptToManuallyInstallCert(currentProxyConfig!! .certificate) }
555566 } else {
556567 Sentry .capture(" Non-OK result $resultCode for requestCode $requestCode " )
557568 mainState = MainState .FAILED
@@ -679,19 +690,40 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
679690 .setTitle(" Manual setup required" )
680691 .setIcon(R .drawable.ic_exclamation_triangle)
681692 .setMessage(
693+ Html .fromHtml(
682694 """
683- Android ${Build .VERSION .RELEASE } doesn't allow automatic certificate setup.
684-
685- To allow HTTP Toolkit to intercept HTTPS traffic:
686-
687- - Open "Encryption & Credentials" in your security settings
688- - Select "Install a certificate", and then "CA Certificate"
689- - Select the HTTP Toolkit certificate
690- """ .trimIndent()
695+ <p>
696+ Android ${Build .VERSION .RELEASE } doesn't allow automatic certificate setup.
697+ </p>
698+ <p>
699+ To allow HTTP Toolkit to intercept HTTPS traffic:
700+ </p>
701+ <ul>
702+ ${if (Build .VERSION .SDK_INT > Build .VERSION_CODES .R ) // Android 12+
703+ """
704+ <li> Open "<b>${
705+ // Slightly different UI for Android 12 and 13:
706+ if (Build .VERSION .SDK_INT == 31 ) " Advanced Settings" else " More security settings"
707+ } </b>" in your security settings</li>
708+ <li> Open "<b>Encryption & Credentials</b>"</li>
709+ """
710+ else
711+ """
712+ <li> Open "<b>Encryption & Credentials</b>" in your security settings</li>
713+ """
714+ }
715+ <li> Select "<b>Install a certificate</b>", then "<b>CA Certificate</b>"</li>
716+ <li> <b>Select the HTTP Toolkit certificate in your Downloads folder</b></li>
717+ </ul>
718+ """ ,0 )
691719 )
692- .setPositiveButton(" Open security settings now " ) { _, _ ->
720+ .setPositiveButton(" Open security settings" ) { _, _ ->
693721 startActivityForResult(Intent (Settings .ACTION_SECURITY_SETTINGS ), INSTALL_CERT_REQUEST )
694722 }
723+ .setNegativeButton(" Cancel" ) { _, _ ->
724+ disconnect()
725+ }
726+ .setCancelable(false )
695727 .show()
696728 }
697729 }
0 commit comments