#11205: Android: fix gateway connection and canvas URL for Tailscale serve
app: android
stale
Cluster:
Android Ed25519 Enhancements
## Summary
Fixes several issues preventing the Android app from connecting to a gateway behind Tailscale serve.
## Changes
### 1. BouncyCastle Ed25519 fallback
Android's native JCA Ed25519 provider fails on some devices (observed on Pixel 10 Pro XL / Android 16 with "Not initialized" errors). Added BouncyCastle (`bcprov-jdk18on:1.80`) as a fallback for both key generation and signing. The code tries the system provider first, then falls back to BouncyCastle.
### 2. Auto-TLS for .ts.net hostnames
Manual connections to `.ts.net` hostnames now automatically use `wss://` even without the "Require TLS" toggle, since Tailscale serve only speaks HTTPS on port 443.
### 3. Fix operator session origin check
The operator session used client ID `openclaw-control-ui`, which triggers the gateway's browser origin check (`checkBrowserOrigin`). Native apps don't send `Origin` headers, so this always failed. Changed to `openclaw-android`.
### 4. Gateway Token and Password UI
Added `OutlinedTextField` inputs for Gateway Token and Gateway Password in the Advanced settings section, matching the iOS app's `SettingsTab.swift`.
### 5. Fix canvas host URL for Tailscale serve
The canvas URL normalization was using the raw gateway port (18789/18793) instead of the Tailscale serve port (443). Added `.ts.net` detection to use `https://` on the default HTTPS port.
## Testing
Tested on Pixel 10 Pro XL (Android 16) connecting to a gateway with:
- `gateway.tailscale.mode: "serve"`
- `gateway.auth.allowTailscale: true`
- `gateway.bind: "loopback"`
Verified:
- ✅ Node connection via Tailscale serve
- ✅ Operator connection (chat/config)
- ✅ Canvas/A2UI loading via HTTPS
- ✅ Device pairing flow
- ✅ Location capability after enabling in app settings
## Notes
- BouncyCastle adds ~2MB to APK size
- Related to #5819 and #5867 which address similar issues
- AI-assisted (Claude), fully tested on hardware
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR updates the Android client to better support gateways behind Tailscale Serve by (1) adding a BouncyCastle Ed25519 fallback for keygen/signing, (2) auto-enabling TLS/port 443 behavior for manual `.ts.net` connections, (3) changing the operator client ID to avoid the gateway’s browser-origin check, (4) adding UI fields for gateway token/password in Advanced settings, and (5) improving canvas host URL normalization to preserve path/query and to prefer HTTPS for tailnet DNS / `.ts.net` hosts while using `endpoint.canvasPort` where applicable.
Within the changed files, the crypto fallback path is internally consistent (BC provider registered, PKCS8 storage preserved, and signing uses either system JCA or BC JCE/lightweight API depending on stored key bytes). The manual connection and canvas URL changes align with the goal of making Tailscale Serve (HTTPS/443) work without requiring the user to manually toggle TLS.
<h3>Confidence Score: 5/5</h3>
- This PR appears safe to merge with minimal risk.
- Reviewed all changed files and traced the updated flows for manual `.ts.net` connections, TLS resolution, canvas URL normalization, and Ed25519 keygen/signing. The changes are cohesive, compile-time safe, and do not introduce any clear runtime faults in the updated paths; prior review threads called out earlier issues that appear addressed in the current head commit (e.g., consistent PKCS8 storage and port preservation).
- No files require special attention
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#13321: android/gateway: harden manual connect identity and A2UI UX
by m888m · 2026-02-10
82.6%
#5867: Android: Add BouncyCastle Ed25519 fallback and gateway token UI
by brandonpollack23 · 2026-02-01
82.2%
#2530: fix(gateway): improve auth error for native apps
by Episkey-G · 2026-01-27
78.0%
#10508: fix(android): fix identity signature failure on Android devices
by kilbertert · 2026-02-06
76.9%
#14564: fix(gateway): crashes on startup when tailscale meets non-loopback ...
by yinghaosang · 2026-02-12
76.6%
#21772: [Bug]: Allow ws:// to Tailscale CGNAT addresses
by AIflow-Labs · 2026-02-20
76.5%
#20422: Fix/tailscale device pairing
by slagyr · 2026-02-18
76.0%
#19548: fix(android): show scaffold instead of raw JSON on canvas auth errors
by gregmousseau · 2026-02-17
75.9%
#7852: fix(gateway): use port from Host header for canvasHostUrl (reverse ...
by tonimelisma · 2026-02-03
75.9%
#22453: fix(tui): resolve and pass tlsFingerprint for secure connections [A...
by captmoss · 2026-02-21
75.5%