@@ -59,6 +59,9 @@ private fun getCertificateFingerprint(cert: X509Certificate): String {
59
59
return Base64 .encodeToString(fingerprint, Base64 .NO_WRAP )
60
60
}
61
61
62
+ private val ACTIVATE_INTENT = " tech.httptoolkit.android.ACTIVATE"
63
+ private val DEACTIVATE_INTENT = " tech.httptoolkit.android.DEACTIVATE"
64
+
62
65
class MainActivity : AppCompatActivity (), CoroutineScope by MainScope() {
63
66
64
67
private val TAG = MainActivity ::class .simpleName
@@ -137,38 +140,50 @@ class MainActivity : AppCompatActivity(), CoroutineScope by MainScope() {
137
140
override fun onNewIntent (intent : Intent ) {
138
141
super .onNewIntent(intent)
139
142
140
- if (intent.action != Intent .ACTION_VIEW ) {
141
- Log .w(TAG , " Unknown intent. Action ${intent.action} , data: ${intent.data} " )
142
- return
143
- }
144
-
145
143
app.trackEvent(" Setup" , " action-view" )
146
144
147
- if (app.lastProxy != null && isVpnConfigured()) {
148
- Log .i(TAG , " Showing prompt for ACTION_VIEW intent" )
149
-
150
- // If we were started from an intent (e.g. another barcode scanner/link), and we
151
- // had a proxy before (so no prompts required) then confirm before starting the VPN.
152
- // Without this any QR code you scan could instantly MitM you.
153
- MaterialAlertDialogBuilder (this )
154
- .setTitle(" Enable Interception" )
155
- .setIcon(R .drawable.ic_exclamation_triangle)
156
- .setMessage(
157
- " Do you want to share all this device's HTTP traffic with HTTP Toolkit?" +
158
- " \n\n " +
159
- " Only accept this if you trust the source."
160
- )
161
- .setPositiveButton(" Enable" ) { _, _ ->
162
- Log .i(TAG , " Prompt confirmed" )
145
+ when (intent.action) {
146
+ // ACTION_VIEW means that somebody had the app installed, and scanned the barcode with
147
+ // a separate barcode app anyway (or opened the QR code URL in a browser)
148
+ Intent .ACTION_VIEW -> {
149
+ if (app.lastProxy != null && isVpnConfigured()) {
150
+ Log .i(TAG , " Showing prompt for ACTION_VIEW intent" )
151
+
152
+ // If we were started from an intent (e.g. another barcode scanner/link), and we
153
+ // had a proxy before (so no prompts required) then confirm before starting the VPN.
154
+ // Without this any QR code you scan could instantly MitM you.
155
+ MaterialAlertDialogBuilder (this )
156
+ .setTitle(" Enable Interception" )
157
+ .setIcon(R .drawable.ic_exclamation_triangle)
158
+ .setMessage(
159
+ " Do you want to share all this device's HTTP traffic with HTTP Toolkit?" +
160
+ " \n\n " +
161
+ " Only accept this if you trust the source."
162
+ )
163
+ .setPositiveButton(" Enable" ) { _, _ ->
164
+ Log .i(TAG , " Prompt confirmed" )
165
+ launch { connectToVpnFromUrl(intent.data!! ) }
166
+ }
167
+ .setNegativeButton(" Cancel" ) { _, _ ->
168
+ Log .i(TAG , " Prompt cancelled" )
169
+ }
170
+ .show()
171
+ } else {
172
+ Log .i(TAG , " Launching from ACTION_VIEW intent" )
163
173
launch { connectToVpnFromUrl(intent.data!! ) }
164
174
}
165
- .setNegativeButton(" Cancel" ) { _, _ ->
166
- Log .i(TAG , " Prompt cancelled" )
167
- }
168
- .show()
169
- } else {
170
- Log .i(TAG , " Launching from ACTION_VIEW intent" )
171
- launch { connectToVpnFromUrl(intent.data!! ) }
175
+ }
176
+
177
+ // RPC setup API, used by ADB to enable/disable without prompts.
178
+ // Permission required, checked for via activity-alias in the manifest
179
+ ACTIVATE_INTENT -> {
180
+ launch { connectToVpnFromUrl(intent.data!! ) }
181
+ }
182
+ DEACTIVATE_INTENT -> {
183
+ disconnect()
184
+ }
185
+
186
+ else -> Log .w(TAG , " Unknown intent. Action ${intent.action} , data: ${intent.data} " )
172
187
}
173
188
}
174
189
0 commit comments