Skip to content

Commit 35e1fc5

Browse files
committed
Fix android tile service
Fix some issues
1 parent 201062d commit 35e1fc5

File tree

26 files changed

+137
-90
lines changed

26 files changed

+137
-90
lines changed

android/app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666

6767
<activity
6868
android:name=".TempActivity"
69+
android:excludeFromRecents="true"
6970
android:exported="true"
7071
android:theme="@style/TransparentTheme">
7172
<intent-filter>

android/app/src/main/kotlin/com/follow/clash/BroadcastReceiver.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ class BroadcastReceiver : BroadcastReceiver() {
2020

2121
BroadcastAction.SERVICE_DESTROYED.action -> {
2222
GlobalState.log("Receiver service destroyed")
23-
State.handleStopServiceAction()
23+
GlobalState.launch {
24+
State.handleStopServiceAction()
25+
}
2426
}
2527
}
2628
}

android/app/src/main/kotlin/com/follow/clash/State.kt

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,30 @@ object State {
6565
}
6666

6767
suspend fun handleStartServiceAction() {
68-
tilePlugin?.handleStart()
69-
if (flutterEngine != null) {
70-
return
68+
runLock.withLock {
69+
if (runStateFlow.value != RunState.STOP) {
70+
return
71+
}
72+
tilePlugin?.handleStart()
73+
if (flutterEngine != null) {
74+
return
75+
}
76+
startServiceWithEngine()
7177
}
72-
startServiceWithEngine()
78+
7379
}
7480

75-
fun handleStopServiceAction() {
76-
tilePlugin?.handleStop()
77-
if (flutterEngine != null || serviceFlutterEngine != null) {
78-
return
81+
suspend fun handleStopServiceAction() {
82+
runLock.withLock {
83+
if (runStateFlow.value != RunState.START) {
84+
return
85+
}
86+
tilePlugin?.handleStop()
87+
if (flutterEngine != null || serviceFlutterEngine != null) {
88+
return
89+
}
90+
handleStopService()
7991
}
80-
handleStopService()
8192
}
8293

8394
fun handleStartService() {
@@ -90,8 +101,23 @@ object State {
90101
startService()
91102
}
92103

104+
fun handleStopService() {
105+
GlobalState.launch {
106+
runLock.withLock {
107+
if (runStateFlow.value != RunState.START) {
108+
return@launch
109+
}
110+
runStateFlow.tryEmit(RunState.PENDING)
111+
runTime = Service.stopService()
112+
runStateFlow.tryEmit(RunState.STOP)
113+
}
114+
destroyServiceEngine()
115+
}
116+
}
117+
93118
suspend fun destroyServiceEngine() {
94119
runLock.withLock {
120+
GlobalState.log("Destroy service engine")
95121
withContext(Dispatchers.Main) {
96122
runCatching {
97123
serviceFlutterEngine?.destroy()
@@ -101,28 +127,32 @@ object State {
101127
}
102128
}
103129

104-
suspend fun startServiceWithEngine() {
105-
runLock.withLock {
106-
if (serviceFlutterEngine != null || runStateFlow.value == RunState.PENDING || runStateFlow.value == RunState.START) {
107-
return
108-
}
109-
withContext(Dispatchers.Main) {
110-
serviceFlutterEngine = FlutterEngine(GlobalState.application)
111-
serviceFlutterEngine?.plugins?.add(ServicePlugin())
112-
serviceFlutterEngine?.plugins?.add(AppPlugin())
113-
serviceFlutterEngine?.plugins?.add(TilePlugin())
114-
val dartEntrypoint = DartExecutor.DartEntrypoint(
115-
FlutterInjector.instance().flutterLoader().findAppBundlePath(), "_service"
116-
)
117-
serviceFlutterEngine?.dartExecutor?.executeDartEntrypoint(dartEntrypoint)
130+
private fun startServiceWithEngine() {
131+
GlobalState.launch {
132+
runLock.withLock {
133+
if (runStateFlow.value != RunState.STOP) {
134+
return@launch
135+
}
136+
GlobalState.log("Create service engine")
137+
withContext(Dispatchers.Main) {
138+
serviceFlutterEngine?.destroy()
139+
serviceFlutterEngine = FlutterEngine(GlobalState.application)
140+
serviceFlutterEngine?.plugins?.add(ServicePlugin())
141+
serviceFlutterEngine?.plugins?.add(AppPlugin())
142+
serviceFlutterEngine?.plugins?.add(TilePlugin())
143+
val dartEntrypoint = DartExecutor.DartEntrypoint(
144+
FlutterInjector.instance().flutterLoader().findAppBundlePath(), "_service"
145+
)
146+
serviceFlutterEngine?.dartExecutor?.executeDartEntrypoint(dartEntrypoint)
147+
}
118148
}
119149
}
120150
}
121151

122152
private fun startService() {
123153
GlobalState.launch {
124154
runLock.withLock {
125-
if (runStateFlow.value == RunState.PENDING || runStateFlow.value == RunState.START) {
155+
if (runStateFlow.value != RunState.STOP) {
126156
return@launch
127157
}
128158
runStateFlow.tryEmit(RunState.PENDING)
@@ -141,20 +171,6 @@ object State {
141171
}
142172

143173
}
144-
145-
fun handleStopService() {
146-
GlobalState.launch {
147-
runLock.withLock {
148-
if (runStateFlow.value == RunState.PENDING || runStateFlow.value == RunState.STOP) {
149-
return@launch
150-
}
151-
runStateFlow.tryEmit(RunState.PENDING)
152-
runTime = Service.stopService()
153-
runStateFlow.tryEmit(RunState.STOP)
154-
}
155-
destroyServiceEngine()
156-
}
157-
}
158174
}
159175

160176

android/app/src/main/kotlin/com/follow/clash/TempActivity.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,9 @@ class TempActivity : Activity(),
2121
}
2222

2323
QuickAction.STOP.action -> {
24-
State.handleStopServiceAction()
24+
launch {
25+
State.handleStopServiceAction()
26+
}
2527
}
2628

2729
QuickAction.TOGGLE.action -> {
@@ -30,6 +32,6 @@ class TempActivity : Activity(),
3032
}
3133
}
3234
}
33-
finishAndRemoveTask()
35+
finish()
3436
}
3537
}

core/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module core
22

3-
go 1.25
3+
go 1.20
44

55
replace github.com/metacubex/mihomo => ./Clash.Meta
66

core/go.sum

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
github.com/RyuaNerin/go-krypto v1.3.0 h1:smavTzSMAx8iuVlGb4pEwl9MD2qicqMzuXR2QWp2/Pg=
22
github.com/RyuaNerin/go-krypto v1.3.0/go.mod h1:9R9TU936laAIqAmjcHo/LsaXYOZlymudOAxjaBf62UM=
33
github.com/RyuaNerin/testingutil v0.1.0 h1:IYT6JL57RV3U2ml3dLHZsVtPOP6yNK7WUVdzzlpNrss=
4-
github.com/RyuaNerin/testingutil v0.1.0/go.mod h1:yTqj6Ta/ycHMPJHRyO12Mz3VrvTloWOsy23WOZH19AA=
54
github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344 h1:cDVUiFo+npB0ZASqnw4q90ylaVAbnYyx0JYqK4YcGok=
65
github.com/Yawning/aez v0.0.0-20211027044916-e49e68abd344/go.mod h1:9pIqrY6SXNL8vjRQE5Hd/OL5GyK/9MrGUWs87z/eFfk=
76
github.com/ajg/form v1.5.1 h1:t9c7v8JUKu/XxOGBU0yjNpaMloxGEJhUkqFRq0ibGeU=
@@ -32,7 +31,6 @@ github.com/ericlagergren/aegis v0.0.0-20250325060835-cd0defd64358/go.mod h1:hkIF
3231
github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391 h1:8j2RH289RJplhA6WfdaPqzg1MjH2K8wX5e0uhAxrw2g=
3332
github.com/ericlagergren/polyval v0.0.0-20220411101811-e25bc10ba391/go.mod h1:K2R7GhgxrlJzHw2qiPWsCZXf/kXEJN9PLnQK73Ll0po=
3433
github.com/ericlagergren/saferand v0.0.0-20220206064634-960a4dd2bc5c h1:RUzBDdZ+e/HEe2Nh8lYsduiPAZygUfVXJn0Ncj5sHMg=
35-
github.com/ericlagergren/saferand v0.0.0-20220206064634-960a4dd2bc5c/go.mod h1:ETASDWf/FmEb6Ysrtd1QhjNedUU/ZQxBCRLh60bQ/UI=
3634
github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1 h1:tlDMEdcPRQKBEz5nGDMvswiajqh7k8ogWRlhRwKy5mY=
3735
github.com/ericlagergren/siv v0.0.0-20220507050439-0b757b3aa5f1/go.mod h1:4RfsapbGx2j/vU5xC/5/9qB3kn9Awp1YDiEnN43QrJ4=
3836
github.com/ericlagergren/subtle v0.0.0-20220507045147-890d697da010 h1:fuGucgPk5dN6wzfnxl3D0D3rVLw4v2SbBT9jb4VnxzA=
@@ -46,7 +44,6 @@ github.com/go-chi/chi/v5 v5.2.3/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hH
4644
github.com/go-chi/render v1.0.3 h1:AsXqd2a1/INaIfUSKq3G5uA8weYx20FOsM7uSoCyyt4=
4745
github.com/go-chi/render v1.0.3/go.mod h1:/gr3hVkmYR0YlEy3LxCuVRFzEu9Ruok+gFqbIofjao0=
4846
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
49-
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
5047
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
5148
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
5249
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
@@ -61,7 +58,6 @@ github.com/gofrs/uuid/v5 v5.3.2 h1:2jfO8j3XgSwlz/wHqemAEugfnTlikAYHhnqQ8Xh4fE0=
6158
github.com/gofrs/uuid/v5 v5.3.2/go.mod h1:CDOjlDMVAtN56jqyRUZh58JT31Tiw7/oQyEXZV+9bD8=
6259
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
6360
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
64-
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
6561
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
6662
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
6763
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
@@ -71,7 +67,6 @@ github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
7167
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38 h1:yAJXTCF9TqKcTiHJAE8dj7HMvPfh66eeA2JYW7eFpSE=
7268
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
7369
github.com/google/tink/go v1.6.1 h1:t7JHqO8Ath2w2ig5vjwQYJzhGEZymedQc90lQXUBa4I=
74-
github.com/google/tink/go v1.6.1/go.mod h1:IGW53kTgag+st5yPhKKwJ6u2l+SSp5/v9XF7spovjlY=
7570
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
7671
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905 h1:q3OEI9RaN/wwcx+qgGo6ZaoJkCiDYe/gjDLfq7lQQF4=
7772
github.com/insomniacslk/dhcp v0.0.0-20250109001534-8abf58130905/go.mod h1:VvGYjkZoJyKqlmT1yzakUs4mfKMNB0XdODP0+rdml6k=
@@ -157,7 +152,6 @@ github.com/oasisprotocol/deoxysii v0.0.0-20220228165953-2091330c22b7/go.mod h1:U
157152
github.com/onsi/ginkgo/v2 v2.9.5 h1:+6Hr4uxzP4XIUyAkg61dWBw8lb/gc4/X5luuxN/EC+Q=
158153
github.com/onsi/ginkgo/v2 v2.9.5/go.mod h1:tvAoo1QUJwNEU2ITftXTpR7R1RbCzoZUOs3RonqW57k=
159154
github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
160-
github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
161155
github.com/openacid/errors v0.8.1/go.mod h1:GUQEJJOJE3W9skHm8E8Y4phdl2LLEN8iD7c5gcGgdx0=
162156
github.com/openacid/low v0.1.21 h1:Tr2GNu4N/+rGRYdOsEHOE89cxUIaDViZbVmKz29uKGo=
163157
github.com/openacid/low v0.1.21/go.mod h1:q+MsKI6Pz2xsCkzV4BLj7NR5M4EX0sGz5AqotpZDVh0=
@@ -198,7 +192,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO
198192
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
199193
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
200194
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
201-
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
202195
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 h1:tHNk7XK9GkmKUR6Gh8gVBKXc2MVSZ4G/NnWLtzw4gNA=
203196
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
204197
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
@@ -213,7 +206,6 @@ github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV
213206
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
214207
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
215208
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae h1:J0GxkO96kL4WF+AIT3M4mfUVinOCPgf2uUWYFUzN0sM=
216-
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE=
217209
gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7 h1:UNrDfkQqiEYzdMlNsVvBYOAJWZjdktqFE9tQh5BT2+4=
218210
gitlab.com/go-extension/aes-ccm v0.0.0-20230221065045-e58665ef23c7/go.mod h1:E+rxHvJG9H6PUdzq9NRG6csuLN3XUx98BfGOVWNYnXs=
219211
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec h1:FpfFs4EhNehiVfzQttTuxanPIT43FtkkCFypIod8LHo=
@@ -254,7 +246,6 @@ golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
254246
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
255247
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
256248
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
257-
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
258249
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
259250
golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM=
260251
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=

core/hub.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ var (
3333
)
3434

3535
func handleInitClash(paramsString string) bool {
36+
runLock.Lock()
37+
defer runLock.Unlock()
3638
var params = InitParams{}
3739
err := json.Unmarshal([]byte(paramsString), &params)
3840
if err != nil {

core/lib.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ type TunHandler struct {
3737
}
3838

3939
func (th *TunHandler) start(fd int, stack, address, dns string) {
40+
runLock.Lock()
41+
defer runLock.Unlock()
4042
_ = th.limit.Acquire(context.TODO(), 4)
4143
defer th.limit.Release(4)
4244
th.initHook()

lib/controller.dart

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,22 @@ class AppController {
8282
}
8383
}
8484

85+
Future<void> tryStartCore() async {
86+
if (coreController.isCompleted) {
87+
return;
88+
}
89+
globalState.isUserDisconnected = true;
90+
await _connectCore();
91+
await _initCore();
92+
_ref.read(initProvider.notifier).value = true;
93+
if (_ref.read(isStartProvider)) {
94+
await globalState.handleStart();
95+
}
96+
}
97+
8598
Future<void> updateStatus(bool isStart) async {
8699
if (isStart) {
100+
await globalState.appController.tryStartCore();
87101
await globalState.handleStart([updateRunTime, updateTraffic]);
88102
final currentLastModified = await _ref
89103
.read(currentProfileProvider)
@@ -466,9 +480,6 @@ class AppController {
466480
Map<String, dynamic>? data,
467481
bool handleError = false,
468482
}) async {
469-
if (globalState.isPre) {
470-
return;
471-
}
472483
if (data != null) {
473484
final tagName = data['tag_name'];
474485
final body = data['body'];
@@ -557,7 +568,6 @@ class AppController {
557568
if (!globalState.isService) Future.delayed(Duration(milliseconds: 300)),
558569
]);
559570
final String message = result[0];
560-
await Future.delayed(commonDuration);
561571
if (message.isNotEmpty) {
562572
_ref.read(coreStatusProvider.notifier).value = CoreStatus.disconnected;
563573
if (context.mounted) {
@@ -962,7 +972,7 @@ class AppController {
962972
final res = await futureFunction();
963973
return res;
964974
} catch (e) {
965-
commonPrint.log('$futureFunction ===> $e', logLevel: LogLevel.warning);
975+
commonPrint.log('$title===> $e', logLevel: LogLevel.warning);
966976
if (realSilence) {
967977
globalState.showNotifier(e.toString());
968978
} else {

lib/core/controller.dart

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ class CoreController {
2929
return _instance!;
3030
}
3131

32+
bool get isCompleted => _interface.completer.isCompleted;
33+
3234
Future<String> preload() {
3335
return _interface.preload();
3436
}
@@ -91,10 +93,17 @@ class CoreController {
9193
return await _interface.updateConfig(updateParams);
9294
}
9395

94-
Future<String> setupConfig(ClashConfig clashConfig) async {
96+
Future<String> setupConfig(
97+
ClashConfig clashConfig, {
98+
VoidCallback? preloadInvoke,
99+
}) async {
95100
await globalState.genConfigFile(clashConfig);
96101
final params = await globalState.getSetupParams();
97-
return await _interface.setupConfig(params);
102+
final res = _interface.setupConfig(params);
103+
if (preloadInvoke != null) {
104+
preloadInvoke();
105+
}
106+
return res;
98107
}
99108

100109
Future<List<Group>> getProxiesGroups({

0 commit comments

Comments
 (0)