69 lines
1.7 KiB
Dart
69 lines
1.7 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
|
|
import 'package:fl_clash/clash/clash.dart';
|
|
import 'package:fl_clash/models/models.dart';
|
|
import 'package:fl_clash/state.dart';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/services.dart';
|
|
|
|
abstract mixin class VpnListener {
|
|
void onDnsChanged(String dns) {}
|
|
}
|
|
|
|
class Vpn {
|
|
static Vpn? _instance;
|
|
late MethodChannel methodChannel;
|
|
FutureOr<String> Function()? handleGetStartForegroundParams;
|
|
|
|
Vpn._internal() {
|
|
methodChannel = const MethodChannel("vpn");
|
|
methodChannel.setMethodCallHandler((call) async {
|
|
switch (call.method) {
|
|
case "gc":
|
|
clashCore.requestGc();
|
|
case "getStartForegroundParams":
|
|
if (handleGetStartForegroundParams != null) {
|
|
return await handleGetStartForegroundParams!();
|
|
}
|
|
return "";
|
|
default:
|
|
for (final VpnListener listener in _listeners) {
|
|
switch (call.method) {
|
|
case "dnsChanged":
|
|
final dns = call.arguments as String;
|
|
listener.onDnsChanged(dns);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
factory Vpn() {
|
|
_instance ??= Vpn._internal();
|
|
return _instance!;
|
|
}
|
|
|
|
final ObserverList<VpnListener> _listeners = ObserverList<VpnListener>();
|
|
|
|
Future<bool?> start(AndroidVpnOptions options) async {
|
|
return await methodChannel.invokeMethod<bool>("start", {
|
|
'data': json.encode(options),
|
|
});
|
|
}
|
|
|
|
Future<bool?> stop() async {
|
|
return await methodChannel.invokeMethod<bool>("stop");
|
|
}
|
|
|
|
void addListener(VpnListener listener) {
|
|
_listeners.add(listener);
|
|
}
|
|
|
|
void removeListener(VpnListener listener) {
|
|
_listeners.remove(listener);
|
|
}
|
|
}
|
|
|
|
Vpn? get vpn => globalState.isService ? Vpn() : null;
|