chore(stage-pocket): migrate MainActivity to kotlin
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'org.jetbrains.kotlin.android'
|
||||
|
||||
android {
|
||||
namespace = "ai.moeru.airi_pocket"
|
||||
@@ -22,6 +23,9 @@ android {
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
kotlinOptions {
|
||||
jvmTarget = '21'
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
package ai.moeru.airi_pocket;
|
||||
|
||||
import android.net.Uri;
|
||||
import android.net.http.SslError;
|
||||
import android.webkit.SslErrorHandler;
|
||||
import android.webkit.WebView;
|
||||
import com.getcapacitor.Bridge;
|
||||
import com.getcapacitor.BridgeActivity;
|
||||
import com.getcapacitor.BridgeWebViewClient;
|
||||
import com.getcapacitor.Logger;
|
||||
|
||||
public class MainActivity extends BridgeActivity {
|
||||
|
||||
@Override
|
||||
protected void load() {
|
||||
super.load();
|
||||
|
||||
if (bridge == null || !bridge.isDevMode()) {
|
||||
return;
|
||||
}
|
||||
|
||||
bridge.setWebViewClient(new DebugTlsBypassWebViewClient(bridge));
|
||||
}
|
||||
|
||||
private static final class DebugTlsBypassWebViewClient extends BridgeWebViewClient {
|
||||
|
||||
private final Bridge bridge;
|
||||
|
||||
private DebugTlsBypassWebViewClient(Bridge bridge) {
|
||||
super(bridge);
|
||||
this.bridge = bridge;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
|
||||
if (shouldBypassDevServerCertificate(error)) {
|
||||
Logger.warn("Bypassing TLS certificate validation for debug dev server: " + error.getUrl());
|
||||
handler.proceed();
|
||||
return;
|
||||
}
|
||||
|
||||
super.onReceivedSslError(view, handler, error);
|
||||
}
|
||||
|
||||
// NOTICE: Android WebView rejects the self-signed HTTPS cert used by the debug dev server.
|
||||
// Keep this bypass debug-only and scoped to the configured dev server origin.
|
||||
private boolean shouldBypassDevServerCertificate(SslError error) {
|
||||
if (error == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String serverUrl = bridge.getServerUrl();
|
||||
String errorUrl = error.getUrl();
|
||||
if (serverUrl == null || serverUrl.isEmpty() || errorUrl == null || errorUrl.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Uri serverUri = Uri.parse(serverUrl);
|
||||
Uri errorUri = Uri.parse(errorUrl);
|
||||
if (!"https".equalsIgnoreCase(serverUri.getScheme())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return serverUri.getHost().equalsIgnoreCase(errorUri.getHost()) && normalizePort(serverUri) == normalizePort(errorUri);
|
||||
}
|
||||
|
||||
private int normalizePort(Uri uri) {
|
||||
int port = uri.getPort();
|
||||
if (port != -1) {
|
||||
return port;
|
||||
}
|
||||
|
||||
if ("https".equalsIgnoreCase(uri.getScheme())) {
|
||||
return 443;
|
||||
}
|
||||
|
||||
if ("http".equalsIgnoreCase(uri.getScheme())) {
|
||||
return 80;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package ai.moeru.airi_pocket
|
||||
|
||||
import android.net.Uri
|
||||
import android.net.http.SslError
|
||||
import android.webkit.SslErrorHandler
|
||||
import android.webkit.WebView
|
||||
import com.getcapacitor.Bridge
|
||||
import com.getcapacitor.BridgeActivity
|
||||
import com.getcapacitor.BridgeWebViewClient
|
||||
import com.getcapacitor.Logger
|
||||
|
||||
class MainActivity : BridgeActivity() {
|
||||
|
||||
override fun load() {
|
||||
super.load()
|
||||
|
||||
val bridge = bridge ?: return
|
||||
if (!bridge.isDevMode) {
|
||||
return
|
||||
}
|
||||
|
||||
bridge.setWebViewClient(DebugTlsBypassWebViewClient(bridge))
|
||||
}
|
||||
|
||||
private class DebugTlsBypassWebViewClient(
|
||||
private val bridge: Bridge,
|
||||
) : BridgeWebViewClient(bridge) {
|
||||
|
||||
override fun onReceivedSslError(view: WebView, handler: SslErrorHandler, error: SslError) {
|
||||
if (shouldBypassDevServerCertificate(error)) {
|
||||
Logger.warn("Bypassing TLS certificate validation for debug dev server: ${error.url}")
|
||||
handler.proceed()
|
||||
return
|
||||
}
|
||||
|
||||
super.onReceivedSslError(view, handler, error)
|
||||
}
|
||||
|
||||
// NOTICE: Android WebView rejects the self-signed HTTPS cert used by the debug dev server.
|
||||
// Keep this bypass debug-only and scoped to the configured dev server origin.
|
||||
private fun shouldBypassDevServerCertificate(error: SslError?): Boolean {
|
||||
val serverUrl = bridge.serverUrl?.takeUnless(String::isEmpty) ?: return false
|
||||
val errorUrl = error?.url?.takeUnless(String::isEmpty) ?: return false
|
||||
|
||||
val serverUri = Uri.parse(serverUrl)
|
||||
if (!serverUri.scheme.equals("https", ignoreCase = true)) {
|
||||
return false
|
||||
}
|
||||
|
||||
val errorUri = Uri.parse(errorUrl)
|
||||
return serverUri.host.equals(errorUri.host, ignoreCase = true)
|
||||
&& normalizePort(serverUri) == normalizePort(errorUri)
|
||||
}
|
||||
|
||||
private fun normalizePort(uri: Uri): Int =
|
||||
uri.port.takeUnless { it == -1 }
|
||||
?: when (uri.scheme?.lowercase()) {
|
||||
"https" -> 443
|
||||
"http" -> 80
|
||||
else -> -1
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ buildscript {
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.13.0'
|
||||
classpath 'com.google.gms:google-services:4.4.4'
|
||||
classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:2.2.21'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
Reference in New Issue
Block a user