fix(ohos): sync dashboard core status on startup#2176
Open
phenix3443 wants to merge 50 commits into
Open
Conversation
…YouTube (#1) * feat(ohos): add HarmonyOS support * fix(ohos): align packaging scaffold with runtime support * fix(ohos): remove unrelated branch changes * fix(ohos): stop tracking local build artifacts * fix(ohos): keep host config reproducible * fix(ohos): tighten scaffold PR scope * docs(ohos): add emulator smoke test flow * docs(ohos): tighten emulator smoke test script * feat(ohos): add HarmonyOS support * fix(ohos): harden interactions on real devices * fix(ohos): preserve custom plugin registration during builds * fix(ohos): run core invocations off the main thread * fix(ohos): restore delay test pending indicator * fix(ohos): route browser TCP through the proxy via the gVisor TUN stack On HarmonyOS the default "mixed" TUN stack handled UDP via gVisor but TCP via the system NAT, which rewrites each SYN to the tun address and relies on a kernel loopback to a local listener. That loopback does not happen inside the OHOS VpnExtension, so every TCP connection through the tun was silently dropped (connection table stayed at count=0) and no browser could load any foreign site, while a loopback curl to the same proxy node worked. Fix (two parts): - core/tun/tun.go: force the gVisor stack on OHOS so TCP is handled entirely in userspace, no kernel loopback. - scripts/ohos/patch_gvisor_tun_fd.sh: gVisor's fdbased.New Fstats the tun fd to detect sockets, which the OHOS sandbox denies; patch isSocketFD to fall back to non-socket (readv) dispatch. Applied idempotently before every OHOS lib build from GoBuilder._patchOhosGvisorTunFd. Verified on Mate 80 Pro: both Chrome and the Huawei native browser fully render YouTube through the VPN. Bundles the supporting feat/ohos-support WIP it depends on: TUN options refactor (core/tun/options*.go), vendored patched sing-tun, fake-ip/DNS and VPN-config changes, NAPI bridge updates, build-tool/script updates, docs, and tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(ohos): connect the UI to the running VPN core for live status, stats and connections When the VPN runs in the com.follow.clash:vpn process, the main app UI had no live channel to the core serving traffic: the dashboard stuck at "连接中…", traffic stats read 0, the connections page stayed empty, and live outbound-mode / node switches did not take effect (they only applied on the next VPN restart). The Go core is the socket client (startServer -> dial) and Dart's CoreService is the server (ServerSocket.bind(unixSocketPath)), but nothing made the VPN-process core dial the main app's socket. Thread the main app's unixSocketPath through startVpn (app.dart, vpn_manager.dart, state.dart) -> AppPlugin.ets -> FlClashVpnAbility, which after startTun calls startEmbeddedCore(coreSocketPath, filesDir). That dlopens the same libclash.so and runs startServerProcessDetached -> dial, so the in-process VPN core connects back to the listening UI socket. The two OHOS-VPN _handleStart(syncCoreState: false) calls are flipped to _handleStart() so the UI subscribes/polls once connected. Also add scripts/ohos/verify_all.sh: a one-command real-device regression suite (uitest find-text/tap-text + 7890 loopback probes) covering install, core, VPN, both browsers loading YouTube, dashboard, proxy tab, profiles, all tools/settings pages, backup, and the two live-link features. 22/22 PASS on Mate 80 Pro. Report in docs/ohos-real-device-test-report.md. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(ohos): show "connected" status once the VPN core link is established The dashboard status chip stayed on "连接中…" (connecting) whenever the VPN was on, because that path never reached CoreStatus.connected: when the VPN runs in the com.follow.clash:vpn process the main app does not go through connectCore()/preload(). Now that the VPN-process core dials the main app's CoreService socket, set CoreStatus.connected after the OHOS-VPN _handleStart() (the link is up by then) and CoreStatus.disconnected when the VPN stops. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(ci): unblock the release pipeline (analyze + test gates green) The branch dropped the `test` dev_dependency (it conflicts with flutter_test's pinned test_api on the current SDK), but 17 tests still imported `package:test/test.dart`, so `flutter analyze` reported 875 errors and the CI test job failed (build needs it). Fixes: - Migrate the 17 pure-Dart tests to `package:flutter_test/flutter_test.dart` (re-exports test/group/expect/setUp/tearDown), compatible with both the pinned SDK and CI's newer Flutter. - database_test.dart: import common.dart for the List.copyAndPut extension. - config_test.dart: the youtube fake-ip-filter asserts now check youtube is NOT excluded (matches the OHOS DNS de-poisoning fix); mock path_provider for the Script.saveWithPath test so it no longer hangs on MissingPluginException. - analysis_options: exclude third_party/** (vendored forks) and tool/** (dev scripts) from the lint surface. - Remove unused imports (picker/task/service), a redundant null check, and 3 never-passed key params (tools.dart) flagged as warnings. Result: `flutter analyze --no-fatal-infos` exits 0 (0 errors, 0 warnings) and `flutter test` passes all 437 tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(ohos): drop leftover [BOOT] debug print tracing from the boot path The boot sequence in main.dart and GlobalState (state.dart) printed ~40 bare `print('[BOOT] ...')` traces that ran on every platform (Windows/macOS/Linux too) and violated the project's own avoid_print lint. Remove them; uncaught boot errors are still surfaced via InitErrorScreen and commonPrint.log. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * feat(ohos): fix build, harden core concurrency, verify VPN on real device Build blockers (HAP now builds): - setup.dart: remove duplicate _readAppVersion definition - AppPlugin.ets/FilePickerDelegate.ets: fix ArkTS any/unknown + null-assignability errors - revert local-plugin registration that made hvigor fail OhmUrl resolution (proxy/wifi_ssid/window_ext source dirs are not buildable modules; AppPlugin/FilePickerPlugin still register via CustomPluginRegistrant) Core concurrency: - server_cgo.go: serialize frame writes on a dedicated writeMu so a stalled Write cannot deadlock stopServer; generation-guarded serveConnection closes the TOCTOU window against stopServerProcessDetached - bridge.cpp: stop dlclose/clearing embedded tracked-core state right after the non-blocking detached launch (was turning StopTrackedCore into a silent no-op) Cleanup: - strip leftover OHOS bring-up debug logging across lib/ - drop one-off probe/repro scripts; gitignore __pycache__ Tests/docs: - add OHOS node + dart regression tests (server_cgo, tracked-core, vpn decisions, app-link/pending-debug, path, etc.) - sync docs/harmonyos.md Verified end-to-end on Mate 80 Pro: built-in browser + Chrome reach Google/YouTube and the X app loads its timeline through the VPN. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(ohos): reconcile node regression tests with build fixes The build fixes changed source that four node source-pattern tests asserted verbatim: - AppPlugin error-callback params are now typed (Any) for ArkTS strict mode - FilePickerDelegate gained a null guard before handlePickedUris - proxy/wifi_ssid/window_ext registration + ohos.pluginClass were reverted (they broke hvigor OhmUrl resolution). Invert those two tests into guards that the har-only plugins stay excluded so the build cannot regress. Also gitignore test/provider.txt (local subscription secret). Gates green: dart analyze 0/0, flutter test, go test, node ohos 92/92. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(ohos): avoid wifi_ssid MissingPluginException on OHOS wifi_ssid is har-only and not registered on OHOS (it was excluded to keep the hvigor build working), so calling into WifiSsidManager throws MissingPluginException there. - Permissions.checkLocationPermissions() runs unconditionally from _initApp on every launch and called WifiSsidManager.checkPermission() on OHOS; skip it (OHOS SSID detection is unavailable, so the location/SSID permission is moot). - Hide the "on demand" (Wi-Fi SSID) advanced-config entry on OHOS; the feature cannot work there (currentSSID is always null via connectivity_manager's OHOS skip) and its permission flow would otherwise throw. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix(ohos): recover VPN from a stale 'started' status after unclean shutdown When the VPN extension is killed uncleanly (process death / force-stop) it can no longer write 'stopped' to flclash-vpn-status.txt, leaving a stale 'started'. That permanently blocked recovery: stopVpn's waitForVpnStoppedStatus never saw 'stopped' and returned "vpn extension did not stop: started", and startVpn's isVpnStatusRunning short-circuited as if the VPN were live. FlClashVpnAbility is a system-managed singleton VPN, so a lingering 'started' after the stop request + timeout means the extension is gone, not refusing to stop. Reconcile that case to stopped (reset the status file, report success) so the next start is not blocked. Verified on Mate 80 Pro: force-stop while running -> restart now recovers with no "did not stop: started" hang (previously required a manual status reset). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
disconnectedinstead ofconnectingTesting
Refs phenix3443#4