From 495f66c2ba2484c9cbcd8e1c23b4c14a7e240bb8 Mon Sep 17 00:00:00 2001 From: atavism Date: Wed, 8 Nov 2023 18:59:20 -0800 Subject: [PATCH] support setting system proxy when vpn switch is toggled --- desktop/app/app.go | 16 ++++++++++++++- lib/ffi.dart | 10 +++++++++ lib/vpn/vpn_switch.dart | 28 +++++++++++++++++++------- macos/Runner.xcodeproj/project.pbxproj | 16 +++++++++------ 4 files changed, 56 insertions(+), 14 deletions(-) diff --git a/desktop/app/app.go b/desktop/app/app.go index 0770c4480..6ea3edc0c 100644 --- a/desktop/app/app.go +++ b/desktop/app/app.go @@ -419,8 +419,22 @@ func (app *App) OnStatsChange(fn func(stats.Stats)) { app.statsTracker.AddListener(fn) } -func (app *App) afterStart(cl *flashlightClient.Client) { +func (app *App) SysproxyOn() { + if err := SysproxyOn(); err != nil { + app.statsTracker.SetAlert( + stats.FAIL_TO_SET_SYSTEM_PROXY, err.Error(), false) + } +} +func (app *App) afterStart(cl *flashlightClient.Client) { + app.OnSettingChange(SNSystemProxy, func(val interface{}) { + enable := val.(bool) + if enable { + app.SysproxyOn() + } else { + SysProxyOff() + } + }) } func (app *App) onConfigUpdate(cfg *config.Global, src config.Source) { diff --git a/lib/ffi.dart b/lib/ffi.dart index a3258bfde..e03b1907d 100644 --- a/lib/ffi.dart +++ b/lib/ffi.dart @@ -4,11 +4,21 @@ import 'package:ffi/src/utf8.dart'; typedef start_func = ffi.Pointer Function(); // FFI fn signature typedef Start = ffi.Pointer Function(); // Dart fn signature + +typedef sysproxy_func = ffi.Pointer Function(); // FFI fn signature +typedef SysProxy = ffi.Pointer Function(); // Dart fn signature + final dylib = ffi.DynamicLibrary.open('liblantern.dylib'); final Start start = dylib.lookup>('Start').asFunction(); +final SysProxy sysProxyOn = + dylib.lookup>('SysProxyOn').asFunction(); + +final SysProxy sysProxyOff = + dylib.lookup>('SysProxyOff').asFunction(); + void loadLibrary() { start(); } \ No newline at end of file diff --git a/lib/vpn/vpn_switch.dart b/lib/vpn/vpn_switch.dart index 3737f904d..6bc2d9b8e 100644 --- a/lib/vpn/vpn_switch.dart +++ b/lib/vpn/vpn_switch.dart @@ -1,4 +1,5 @@ import 'package:lantern/vpn/vpn.dart'; +import 'package:lantern/ffi.dart'; class VPNSwitch extends StatefulWidget { const VPNSwitch({super.key}); @@ -10,6 +11,8 @@ class VPNSwitch extends StatefulWidget { class _VPNSwitchState extends State { // final adHelper = AdHelper(); + String vpnStatus = 'disconnected'; + @override void initState() { super.initState(); @@ -19,11 +22,18 @@ class _VPNSwitchState extends State { bool isIdle(String vpnStatus) => vpnStatus != 'connecting' && vpnStatus != 'disconnecting'; - Future onSwitchTap(bool newValue, String vpnStatus) async { + Future onSwitchTap(bool newValue) async { unawaited(HapticFeedback.lightImpact()); - if (isIdle(vpnStatus)) { - await vpnModel.switchVPN(newValue); + if (Platform.isAndroid) { + await vpnModel.switchVPN(newValue); + } else if (Platform.isMacOS) { + if (vpnStatus == 'connected') { + await sysProxyOff(); + } else { + await sysProxyOn(); + } + } } //add delayed to avoid flickering @@ -35,20 +45,24 @@ class _VPNSwitchState extends State { }, ); } + + setState(() { + vpnStatus = newValue ? 'connected' : 'disconnected'; + }); + } @override Widget build(BuildContext context) { // Still working on ads feature - - const vpnStatus = 'disconnected'; return Transform.scale( scale: 2, child: FlutterSwitch( - value: vpnStatus == 'connected' || vpnStatus == 'disconnecting', + value: this.vpnStatus == 'connected' || this.vpnStatus == 'disconnecting', + //value: true, activeColor: onSwitchColor, inactiveColor: offSwitchColor, - onToggle: (bool newValue) => onSwitchTap(newValue, vpnStatus), + onToggle: (bool newValue) => onSwitchTap(newValue), ), ); // return sessionModel diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index 33f683d45..f526a5447 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -27,7 +27,9 @@ 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; }; 33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; }; - 5FCF3F8E2AFC652C009D6A84 /* liblantern.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 5FCF3F8C2AFC6498009D6A84 /* liblantern.dylib */; }; + 5FCF3F922AFC7D4C009D6A84 /* liblantern.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 5FCF3F912AFC7D4C009D6A84 /* liblantern.dylib */; }; + 5FCF3F942AFC7D54009D6A84 /* liblantern.dylib in Resources */ = {isa = PBXBuildFile; fileRef = 5FCF3F932AFC7D54009D6A84 /* liblantern.dylib */; }; + 5FCF3F972AFC7E30009D6A84 /* liblantern.dylib in Bundle Framework */ = {isa = PBXBuildFile; fileRef = 5FCF3F912AFC7D4C009D6A84 /* liblantern.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 9DD832B42514BE06F2A57F8F /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 052699D6465AD8C9FB260E23 /* Pods_Runner.framework */; }; B3ED98C3EAD7718A05708BFE /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 335B76D179FE1547C0436C96 /* Pods_RunnerTests.framework */; }; /* End PBXBuildFile section */ @@ -56,6 +58,7 @@ dstPath = ""; dstSubfolderSpec = 10; files = ( + 5FCF3F972AFC7E30009D6A84 /* liblantern.dylib in Bundle Framework */, ); name = "Bundle Framework"; runOnlyForDeploymentPostprocessing = 0; @@ -82,8 +85,8 @@ 33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = ""; }; 33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = ""; }; 5EFCF11B904D986D4A21D577 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; - 5FCF3F8A2AFC648F009D6A84 /* liblantern.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = liblantern.dylib; path = ../desktop/liblantern.dylib; sourceTree = ""; }; - 5FCF3F8C2AFC6498009D6A84 /* liblantern.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = liblantern.dylib; path = ../desktop/liblantern.dylib; sourceTree = ""; }; + 5FCF3F912AFC7D4C009D6A84 /* liblantern.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = liblantern.dylib; path = ../desktop/liblantern.dylib; sourceTree = ""; }; + 5FCF3F932AFC7D54009D6A84 /* liblantern.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = liblantern.dylib; path = ../desktop/liblantern.dylib; sourceTree = ""; }; 62A0CE728A7650DA48C7A079 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = ""; }; 8C9C86E67EAFCD07D44BC397 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; }; @@ -99,6 +102,7 @@ buildActionMask = 2147483647; files = ( B3ED98C3EAD7718A05708BFE /* Pods_RunnerTests.framework in Frameworks */, + 5FCF3F922AFC7D4C009D6A84 /* liblantern.dylib in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -148,7 +152,7 @@ 33CC10E42044A3C60003C045 = { isa = PBXGroup; children = ( - 5FCF3F8C2AFC6498009D6A84 /* liblantern.dylib */, + 5FCF3F932AFC7D54009D6A84 /* liblantern.dylib */, 33FAB671232836740065AC1E /* Runner */, 33CEB47122A05771004F2AC0 /* Flutter */, 331C80D6294CF71000263BE5 /* RunnerTests */, @@ -205,7 +209,7 @@ D73912EC22F37F3D000D13A0 /* Frameworks */ = { isa = PBXGroup; children = ( - 5FCF3F8A2AFC648F009D6A84 /* liblantern.dylib */, + 5FCF3F912AFC7D4C009D6A84 /* liblantern.dylib */, 052699D6465AD8C9FB260E23 /* Pods_Runner.framework */, 335B76D179FE1547C0436C96 /* Pods_RunnerTests.framework */, ); @@ -318,9 +322,9 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 5FCF3F8E2AFC652C009D6A84 /* liblantern.dylib in Resources */, 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */, 33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */, + 5FCF3F942AFC7D54009D6A84 /* liblantern.dylib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; };