From 44a6e50fcc53d5d8a190fb1728e375b0a79334ac Mon Sep 17 00:00:00 2001 From: Mason Huang Date: Thu, 16 Apr 2026 19:22:15 +0800 Subject: [PATCH] Android: modernize WebView and discovery API usage (#67627) * Android: modernize WebView and discovery API usage * Android: narrow discovery API cleanup scope --- .../openclaw/app/gateway/GatewayDiscovery.kt | 69 ++++++++++--------- .../java/ai/openclaw/app/ui/CanvasScreen.kt | 10 +-- 2 files changed, 37 insertions(+), 42 deletions(-) diff --git a/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayDiscovery.kt b/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayDiscovery.kt index f83af46cc65..4fc4c01ed16 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayDiscovery.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/gateway/GatewayDiscovery.kt @@ -12,6 +12,7 @@ import java.io.IOException import java.net.InetSocketAddress import java.nio.ByteBuffer import java.nio.charset.CodingErrorAction +import java.time.Duration import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.Executor import java.util.concurrent.Executors @@ -132,38 +133,38 @@ class GatewayDiscovery( object : NsdManager.ResolveListener { override fun onResolveFailed(serviceInfo: NsdServiceInfo, errorCode: Int) {} - override fun onServiceResolved(resolved: NsdServiceInfo) { - val host = resolved.host?.hostAddress ?: return - val port = resolved.port - if (port <= 0) return + override fun onServiceResolved(resolved: NsdServiceInfo) { + val host = resolved.host?.hostAddress ?: return + val port = resolved.port + if (port <= 0) return - val rawServiceName = resolved.serviceName - val serviceName = BonjourEscapes.decode(rawServiceName) - val displayName = BonjourEscapes.decode(txt(resolved, "displayName") ?: serviceName) - val lanHost = txt(resolved, "lanHost") - val tailnetDns = txt(resolved, "tailnetDns") - val gatewayPort = txtInt(resolved, "gatewayPort") - val canvasPort = txtInt(resolved, "canvasPort") - val tlsEnabled = txtBool(resolved, "gatewayTls") - val tlsFingerprint = txt(resolved, "gatewayTlsSha256") - val id = stableId(serviceName, "local.") - localById[id] = - GatewayEndpoint( - stableId = id, - name = displayName, - host = host, - port = port, - lanHost = lanHost, - tailnetDns = tailnetDns, - gatewayPort = gatewayPort, - canvasPort = canvasPort, - tlsEnabled = tlsEnabled, - tlsFingerprintSha256 = tlsFingerprint, - ) - publish() - } - }, - ) + val rawServiceName = resolved.serviceName + val serviceName = BonjourEscapes.decode(rawServiceName) + val displayName = BonjourEscapes.decode(txt(resolved, "displayName") ?: serviceName) + val lanHost = txt(resolved, "lanHost") + val tailnetDns = txt(resolved, "tailnetDns") + val gatewayPort = txtInt(resolved, "gatewayPort") + val canvasPort = txtInt(resolved, "canvasPort") + val tlsEnabled = txtBool(resolved, "gatewayTls") + val tlsFingerprint = txt(resolved, "gatewayTlsSha256") + val id = stableId(serviceName, "local.") + localById[id] = + GatewayEndpoint( + stableId = id, + name = displayName, + host = host, + port = port, + lanHost = lanHost, + tailnetDns = tailnetDns, + gatewayPort = gatewayPort, + canvasPort = canvasPort, + tlsEnabled = tlsEnabled, + tlsFingerprintSha256 = tlsFingerprint, + ) + publish() + } + }, + ) } private fun publish() { @@ -350,7 +351,7 @@ class GatewayDiscovery( } private fun records(msg: Message?, section: Int): List { - return msg?.getSectionArray(section)?.toList() ?: emptyList() + return msg?.getSection(section).orEmpty() } private fun keyName(raw: String): String { @@ -426,14 +427,14 @@ class GatewayDiscovery( try { SimpleResolver().apply { setAddress(InetSocketAddress(addr, 53)) - setTimeout(3) + setTimeout(Duration.ofSeconds(3)) } } catch (_: Throwable) { null } } if (resolvers.isEmpty()) return null - ExtendedResolver(resolvers.toTypedArray()).apply { setTimeout(3) } + ExtendedResolver(resolvers.toTypedArray()).apply { setTimeout(Duration.ofSeconds(3)) } } catch (_: Throwable) { null } diff --git a/apps/android/app/src/main/java/ai/openclaw/app/ui/CanvasScreen.kt b/apps/android/app/src/main/java/ai/openclaw/app/ui/CanvasScreen.kt index e299dea2371..c4366aa903b 100644 --- a/apps/android/app/src/main/java/ai/openclaw/app/ui/CanvasScreen.kt +++ b/apps/android/app/src/main/java/ai/openclaw/app/ui/CanvasScreen.kt @@ -56,10 +56,10 @@ fun CanvasScreen(viewModel: MainViewModel, visible: Boolean, modifier: Modifier settings.builtInZoomControls = false settings.displayZoomControls = false settings.setSupportZoom(false) + // targetSdk 33+ ignores Force Dark APIs, so only opt out through the supported + // algorithmic darkening flag when this WebView implementation exposes it. if (WebViewFeature.isFeatureSupported(WebViewFeature.ALGORITHMIC_DARKENING)) { WebSettingsCompat.setAlgorithmicDarkeningAllowed(settings, false) - } else { - disableForceDarkIfSupported(settings) } if (isDebuggable) { Log.d("OpenClawWebView", "userAgent: ${settings.userAgentString}") @@ -157,12 +157,6 @@ fun CanvasScreen(viewModel: MainViewModel, visible: Boolean, modifier: Modifier ) } -private fun disableForceDarkIfSupported(settings: WebSettings) { - if (!WebViewFeature.isFeatureSupported(WebViewFeature.FORCE_DARK)) return - @Suppress("DEPRECATION") - WebSettingsCompat.setForceDark(settings, WebSettingsCompat.FORCE_DARK_OFF) -} - internal class CanvasA2UIActionBridge( private val isTrustedPage: () -> Boolean, private val onMessage: (String) -> Unit,