Skip to content

Commit

Permalink
Fix android system proxy not effective
Browse files Browse the repository at this point in the history
Add macos arm64
  • Loading branch information
chen08209 committed Jul 18, 2024
1 parent 82be4cc commit 3bc3172
Show file tree
Hide file tree
Showing 19 changed files with 187 additions and 86 deletions.
11 changes: 8 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,16 @@ jobs:
os: ubuntu-latest
- platform: windows
os: windows-latest
arch: amd64
- platform: linux
os: ubuntu-latest
arch: amd64
- platform: macos
os: macos-13
arch: amd64
- platform: macos
os: macos-latest
arch: arm64

steps:
- name: Setup Mingw64
Expand Down Expand Up @@ -89,13 +95,12 @@ jobs:
run: flutter pub get

- name: Setup
run: |
dart setup.dart ${{ matrix.platform }}
run: dart setup.dart ${{ matrix.platform }} ${{ matrix.arch && format('--arch {0}', matrix.arch) }}

- name: Upload
uses: actions/upload-artifact@v4
with:
name: artifact-${{ matrix.platform }}
name: artifact-${{ matrix.platform }}-${{ matrix.arch && format('--arch {0}', matrix.arch) }}
path: ./dist
retention-days: 1
overwrite: true
Expand Down
43 changes: 43 additions & 0 deletions core/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//go:build android

package main

import "C"
import (
"encoding/json"
"fmt"
)

type AccessControl struct {
Mode string `json:"mode"`
AcceptList []string `json:"acceptList"`
RejectList []string `json:"rejectList"`
IsFilterSystemApp bool `json:"isFilterSystemApp"`
}

type AndroidProps struct {
AccessControl *AccessControl `json:"accessControl"`
AllowBypass bool `json:"allowBypass"`
SystemProxy bool `json:"systemProxy"`
}

var androidProps AndroidProps

//export getAndroidProps
func getAndroidProps() *C.char {
data, err := json.Marshal(androidProps)
if err != nil {
fmt.Println("Error:", err)
return C.CString("")
}
return C.CString(string(data))
}

//export setAndroidProps
func setAndroidProps(s *C.char) {
paramsString := C.GoString(s)
err := json.Unmarshal([]byte(paramsString), &androidProps)
if err != nil {
return
}
}
15 changes: 15 additions & 0 deletions lib/clash/core.dart
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,21 @@ class ClashCore {
return VersionInfo.fromJson(versionInfo);
}

setProps(Props props) {
final propsChar = json.encode(props).toNativeUtf8().cast<Char>();
clashFFI.setAndroidProps(propsChar);
malloc.free(propsChar);
}

Props getProps() {
final androidPropsRaw = clashFFI.getAndroidProps();
final androidProps = json.decode(
androidPropsRaw.cast<Utf8>().toDartString(),
);
clashFFI.freeCString(androidPropsRaw);
return Props.fromJson(androidProps);
}

Traffic getTraffic() {
final trafficRaw = clashFFI.getTraffic();
final trafficMap = json.decode(trafficRaw.cast<Utf8>().toDartString());
Expand Down
24 changes: 24 additions & 0 deletions lib/clash/generated/clash_ffi.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5499,6 +5499,30 @@ class ClashFFI {
late final _setProcessMap =
_setProcessMapPtr.asFunction<void Function(ffi.Pointer<ffi.Char>)>();

ffi.Pointer<ffi.Char> getAndroidProps() {
return _getAndroidProps();
}

late final _getAndroidPropsPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Char> Function()>>(
'getAndroidProps');
late final _getAndroidProps =
_getAndroidPropsPtr.asFunction<ffi.Pointer<ffi.Char> Function()>();

void setAndroidProps(
ffi.Pointer<ffi.Char> s,
) {
return _setAndroidProps(
s,
);
}

late final _setAndroidPropsPtr =
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Pointer<ffi.Char>)>>(
'setAndroidProps');
late final _setAndroidProps =
_setAndroidPropsPtr.asFunction<void Function(ffi.Pointer<ffi.Char>)>();

void startTUN(
int fd,
int port,
Expand Down
4 changes: 2 additions & 2 deletions lib/common/proxy.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ class ProxyManager {

DateTime? get startTime => _proxy.startTime;

Future<bool?> startProxy({required int port, String? args}) async {
return await _proxy.startProxy(port, args);
Future<bool?> startProxy({required int port}) async {
return await _proxy.startProxy(port);
}

Future<bool?> stopProxy() async {
Expand Down
1 change: 1 addition & 0 deletions lib/fragments/proxies/tab.dart
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class _ProxiesTabFragmentState extends State<ProxiesTabFragment>
return SizedBox(
width: double.infinity,
child: Wrap(
alignment: WrapAlignment.center,
runSpacing: 8,
spacing: 8,
children: [
Expand Down
4 changes: 2 additions & 2 deletions lib/models/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ class AccessControl with _$AccessControl {
class Props with _$Props {
const factory Props({
AccessControl? accessControl,
bool? allowBypass,
bool? systemProxy,
required bool allowBypass,
required bool systemProxy,
}) = _Props;

factory Props.fromJson(Map<String, Object?> json) => _$PropsFromJson(json);
Expand Down
51 changes: 26 additions & 25 deletions lib/models/generated/config.freezed.dart
Original file line number Diff line number Diff line change
Expand Up @@ -247,8 +247,8 @@ Props _$PropsFromJson(Map<String, dynamic> json) {
/// @nodoc
mixin _$Props {
AccessControl? get accessControl => throw _privateConstructorUsedError;
bool? get allowBypass => throw _privateConstructorUsedError;
bool? get systemProxy => throw _privateConstructorUsedError;
bool get allowBypass => throw _privateConstructorUsedError;
bool get systemProxy => throw _privateConstructorUsedError;

Map<String, dynamic> toJson() => throw _privateConstructorUsedError;
@JsonKey(ignore: true)
Expand All @@ -260,8 +260,7 @@ abstract class $PropsCopyWith<$Res> {
factory $PropsCopyWith(Props value, $Res Function(Props) then) =
_$PropsCopyWithImpl<$Res, Props>;
@useResult
$Res call(
{AccessControl? accessControl, bool? allowBypass, bool? systemProxy});
$Res call({AccessControl? accessControl, bool allowBypass, bool systemProxy});

$AccessControlCopyWith<$Res>? get accessControl;
}
Expand All @@ -280,22 +279,22 @@ class _$PropsCopyWithImpl<$Res, $Val extends Props>
@override
$Res call({
Object? accessControl = freezed,
Object? allowBypass = freezed,
Object? systemProxy = freezed,
Object? allowBypass = null,
Object? systemProxy = null,
}) {
return _then(_value.copyWith(
accessControl: freezed == accessControl
? _value.accessControl
: accessControl // ignore: cast_nullable_to_non_nullable
as AccessControl?,
allowBypass: freezed == allowBypass
allowBypass: null == allowBypass
? _value.allowBypass
: allowBypass // ignore: cast_nullable_to_non_nullable
as bool?,
systemProxy: freezed == systemProxy
as bool,
systemProxy: null == systemProxy
? _value.systemProxy
: systemProxy // ignore: cast_nullable_to_non_nullable
as bool?,
as bool,
) as $Val);
}

Expand All @@ -319,8 +318,7 @@ abstract class _$$PropsImplCopyWith<$Res> implements $PropsCopyWith<$Res> {
__$$PropsImplCopyWithImpl<$Res>;
@override
@useResult
$Res call(
{AccessControl? accessControl, bool? allowBypass, bool? systemProxy});
$Res call({AccessControl? accessControl, bool allowBypass, bool systemProxy});

@override
$AccessControlCopyWith<$Res>? get accessControl;
Expand All @@ -338,40 +336,43 @@ class __$$PropsImplCopyWithImpl<$Res>
@override
$Res call({
Object? accessControl = freezed,
Object? allowBypass = freezed,
Object? systemProxy = freezed,
Object? allowBypass = null,
Object? systemProxy = null,
}) {
return _then(_$PropsImpl(
accessControl: freezed == accessControl
? _value.accessControl
: accessControl // ignore: cast_nullable_to_non_nullable
as AccessControl?,
allowBypass: freezed == allowBypass
allowBypass: null == allowBypass
? _value.allowBypass
: allowBypass // ignore: cast_nullable_to_non_nullable
as bool?,
systemProxy: freezed == systemProxy
as bool,
systemProxy: null == systemProxy
? _value.systemProxy
: systemProxy // ignore: cast_nullable_to_non_nullable
as bool?,
as bool,
));
}
}

/// @nodoc
@JsonSerializable()
class _$PropsImpl implements _Props {
const _$PropsImpl({this.accessControl, this.allowBypass, this.systemProxy});
const _$PropsImpl(
{this.accessControl,
required this.allowBypass,
required this.systemProxy});

factory _$PropsImpl.fromJson(Map<String, dynamic> json) =>
_$$PropsImplFromJson(json);

@override
final AccessControl? accessControl;
@override
final bool? allowBypass;
final bool allowBypass;
@override
final bool? systemProxy;
final bool systemProxy;

@override
String toString() {
Expand Down Expand Up @@ -413,17 +414,17 @@ class _$PropsImpl implements _Props {
abstract class _Props implements Props {
const factory _Props(
{final AccessControl? accessControl,
final bool? allowBypass,
final bool? systemProxy}) = _$PropsImpl;
required final bool allowBypass,
required final bool systemProxy}) = _$PropsImpl;

factory _Props.fromJson(Map<String, dynamic> json) = _$PropsImpl.fromJson;

@override
AccessControl? get accessControl;
@override
bool? get allowBypass;
bool get allowBypass;
@override
bool? get systemProxy;
bool get systemProxy;
@override
@JsonKey(ignore: true)
_$$PropsImplCopyWith<_$PropsImpl> get copyWith =>
Expand Down
4 changes: 2 additions & 2 deletions lib/models/generated/config.g.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 6 additions & 7 deletions lib/plugins/proxy.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class Proxy extends ProxyPlatform {
return _instance!;
}

Future<bool?> _initService() async {
Future<bool?> initService() async {
return await methodChannel.invokeMethod<bool>("initService");
}

Expand All @@ -46,12 +46,11 @@ class Proxy extends ProxyPlatform {
}

@override
Future<bool?> startProxy(port, args) async {
if (!globalState.isVpnService) {
return await _initService();
}
return await methodChannel
.invokeMethod<bool>("startProxy", {'port': port, 'args': args});
Future<bool?> startProxy(port) async {
return await methodChannel.invokeMethod<bool>("startProxy", {
'port': port,
'args': json.encode(clashCore.getProps()),
});
}

@override
Expand Down
35 changes: 21 additions & 14 deletions lib/state.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';

import 'package:animations/animations.dart';
import 'package:fl_clash/clash/clash.dart';
import 'package:fl_clash/enum/enum.dart';
import 'package:fl_clash/plugins/proxy.dart';
import 'package:fl_clash/widgets/scaffold.dart';
import 'package:flutter/material.dart';
Expand Down Expand Up @@ -72,18 +70,20 @@ class GlobalState {
required Config config,
required ClashConfig clashConfig,
}) async {
final args = config.isAccessControl
? json.encode(
Props(
accessControl: config.accessControl,
allowBypass: config.allowBypass,
),
)
: null;
await proxyManager.startProxy(
port: clashConfig.mixedPort,
args: args,
);
if (!globalState.isVpnService && Platform.isAndroid) {
clashCore.setProps(
Props(
accessControl: config.isAccessControl ? config.accessControl : null,
allowBypass: config.allowBypass,
systemProxy: config.systemProxy,
),
);
await proxy?.initService();
} else {
await proxyManager.startProxy(
port: clashConfig.mixedPort,
);
}
startListenUpdate();
if (Platform.isAndroid) {
return;
Expand Down Expand Up @@ -123,6 +123,13 @@ class GlobalState {
}) async {
appState.isInit = clashCore.isInit;
if (!appState.isInit) {
clashCore.setProps(
Props(
accessControl: config.isAccessControl ? config.accessControl : null,
allowBypass: config.allowBypass,
systemProxy: config.systemProxy,
),
);
appState.isInit = await clashService.init(
config: config,
clashConfig: clashConfig,
Expand Down
2 changes: 1 addition & 1 deletion linux/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)

# libclash.so
set(CLASH_DIR "../libclash/linux/amd64")
set(CLASH_DIR "../libclash/linux")
install(FILES "${CLASH_DIR}/libclash.so" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
COMPONENT Runtime)

Expand Down
Loading

0 comments on commit 3bc3172

Please sign in to comment.