Skip to content

Commit 23e3baf

Browse files
committed
Optimize ip detection
Support android vpn ipv6 inbound switch Support log export Optimize more details
1 parent d522a64 commit 23e3baf

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+35205
-30525
lines changed

android/app/build.gradle

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,22 @@ def isRelease = defStoreFile.exists() && defStorePassword != null && defKeyAlias
3434
android {
3535
namespace "com.follow.clash"
3636
compileSdkVersion 34
37-
ndkVersion "25.1.8937393"
37+
ndkVersion "27.1.12297006"
3838

3939
compileOptions {
40-
sourceCompatibility JavaVersion.VERSION_1_8
41-
targetCompatibility JavaVersion.VERSION_1_8
40+
sourceCompatibility JavaVersion.VERSION_17
41+
targetCompatibility JavaVersion.VERSION_17
4242
}
4343

4444
kotlinOptions {
45-
jvmTarget = '1.8'
45+
jvmTarget = '17'
4646
}
4747

4848
sourceSets {
4949
main.java.srcDirs += 'src/main/kotlin'
5050
}
5151
signingConfigs {
52-
if (isRelease){
52+
if (isRelease) {
5353
release {
5454
storeFile defStoreFile
5555
storePassword defStorePassword
@@ -74,10 +74,9 @@ android {
7474
applicationIdSuffix '.debug'
7575
}
7676
release {
77-
minifyEnabled true
78-
if(isRelease){
77+
if (isRelease) {
7978
signingConfig signingConfigs.release
80-
}else{
79+
} else {
8180
signingConfig signingConfigs.debug
8281
}
8382
proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro"

android/app/src/main/AndroidManifest.xml

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,22 @@
1010

1111
<uses-permission android:name="android.permission.INTERNET" />
1212
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
13+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"
14+
tools:ignore="SystemPermissionTypo" />
1315
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
1416
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
1517
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
1618
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
17-
<uses-permission
18-
android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"
19-
tools:ignore="SystemPermissionTypo" />
19+
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
2020
<uses-permission
2121
android:name="android.permission.QUERY_ALL_PACKAGES"
2222
tools:ignore="QueryAllPackagesPermission" />
2323

2424
<application
2525
android:name="${applicationName}"
26-
android:enableOnBackInvokedCallback="true"
27-
android:extractNativeLibs="true"
2826
android:icon="@mipmap/ic_launcher"
29-
android:label="FlClash"
30-
android:networkSecurityConfig="@xml/network_security_config"
31-
tools:targetApi="tiramisu">
27+
android:hardwareAccelerated="true"
28+
android:label="FlClash">
3229
<activity
3330
android:name="com.follow.clash.MainActivity"
3431
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
@@ -64,6 +61,16 @@
6461

6562
<data android:host="install-config" />
6663
</intent-filter>
64+
</activity>
65+
66+
<!-- <meta-data-->
67+
<!-- android:name="io.flutter.embedding.android.EnableImpeller"-->
68+
<!-- android:value="true" />-->
69+
70+
<activity
71+
android:name=".TempActivity"
72+
android:exported="true"
73+
android:theme="@style/TransparentTheme">
6774
<intent-filter>
6875
<category android:name="android.intent.category.DEFAULT" />
6976
<action android:name="com.follow.clash.action.START" />
@@ -74,14 +81,6 @@
7481
</intent-filter>
7582
</activity>
7683

77-
<!-- <meta-data-->
78-
<!-- android:name="io.flutter.embedding.android.EnableImpeller"-->
79-
<!-- android:value="true" />-->
80-
81-
<activity
82-
android:name=".TempActivity"
83-
android:theme="@style/TransparentTheme" />
84-
8584
<service
8685
android:name=".services.FlClashTileService"
8786
android:exported="true"
@@ -127,12 +126,19 @@
127126
<intent-filter>
128127
<action android:name="android.net.VpnService" />
129128
</intent-filter>
129+
<property
130+
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
131+
android:value="vpn" />
130132
</service>
131133

132134
<service
133135
android:name=".services.FlClashService"
134136
android:exported="false"
135-
android:foregroundServiceType="specialUse" />
137+
android:foregroundServiceType="specialUse">
138+
<property
139+
android:name="android.app.PROPERTY_SPECIAL_USE_FGS_SUBTYPE"
140+
android:value="service" />
141+
</service>
136142

137143
<meta-data
138144
android:name="flutterEmbedding"

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

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,6 @@ import io.flutter.embedding.android.FlutterActivity
1111
import io.flutter.embedding.engine.FlutterEngine
1212

1313
class MainActivity : FlutterActivity() {
14-
override fun onNewIntent(intent: Intent) {
15-
super.onNewIntent(intent)
16-
when (intent.action) {
17-
"com.follow.clash.action.START" -> {
18-
GlobalState.getCurrentTilePlugin()?.handleStart()
19-
}
20-
21-
"com.follow.clash.action.STOP" -> {
22-
GlobalState.getCurrentTilePlugin()?.handleStop()
23-
}
24-
}
25-
}
26-
2714
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
2815
super.configureFlutterEngine(flutterEngine)
2916
flutterEngine.plugins.add(AppPlugin())

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

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@ import android.os.Bundle
66
class TempActivity : Activity() {
77
override fun onCreate(savedInstanceState: Bundle?) {
88
super.onCreate(savedInstanceState)
9+
when (intent.action) {
10+
"com.follow.clash.action.START" -> {
11+
GlobalState.getCurrentTilePlugin()?.handleStart()
12+
}
13+
14+
"com.follow.clash.action.STOP" -> {
15+
GlobalState.getCurrentTilePlugin()?.handleStop()
16+
}
17+
}
918
finishAndRemoveTask()
1019
}
1120
}

android/app/src/main/kotlin/com/follow/clash/models/Dns.kt

Lines changed: 0 additions & 26 deletions
This file was deleted.

android/app/src/main/kotlin/com/follow/clash/models/Props.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ data class Props(
1616
val accessControl: AccessControl?,
1717
val allowBypass: Boolean?,
1818
val systemProxy: Boolean?,
19+
val ipv6: Boolean?,
1920
)
2021

2122
data class TunProps(

android/app/src/main/kotlin/com/follow/clash/plugins/VpnPlugin.kt

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package com.follow.clash.plugins
22

3-
import android.annotation.SuppressLint
43
import android.content.ComponentName
54
import android.content.Context
65
import android.content.Intent
@@ -163,8 +162,7 @@ class VpnPlugin : FlutterPlugin, MethodChannel.MethodCallHandler {
163162
}
164163
}
165164

166-
@SuppressLint("ForegroundServiceType")
167-
fun handleStartVpn() {
165+
private fun handleStartVpn() {
168166
GlobalState.getCurrentAppPlugin()?.requestVpnPermission(context) {
169167
start()
170168
}
@@ -228,7 +226,6 @@ class VpnPlugin : FlutterPlugin, MethodChannel.MethodCallHandler {
228226
onUpdateNetwork()
229227
}
230228

231-
@SuppressLint("ForegroundServiceType")
232229
private fun startForeground(title: String, content: String) {
233230
GlobalState.runLock.withLock {
234231
if (GlobalState.runState.value != RunState.START) return

android/app/src/main/kotlin/com/follow/clash/services/FlClashService.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,13 @@ import android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_SPECIAL_USE
1111
import android.os.Binder
1212
import android.os.Build
1313
import android.os.IBinder
14-
import android.util.Log
1514
import androidx.core.app.NotificationCompat
1615
import com.follow.clash.BaseServiceInterface
1716
import com.follow.clash.MainActivity
1817
import com.follow.clash.models.Props
1918

2019

21-
@SuppressLint("WrongConstant")
20+
2221
class FlClashService : Service(), BaseServiceInterface {
2322

2423
private val binder = LocalBinder()

android/app/src/main/kotlin/com/follow/clash/services/FlClashTileService.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.follow.clash.services
22

3+
import android.annotation.SuppressLint
34
import android.app.PendingIntent
45
import android.content.Intent
56
import android.os.Build
@@ -37,6 +38,7 @@ class FlClashTileService : TileService() {
3738
GlobalState.runState.observeForever(observer)
3839
}
3940

41+
@SuppressLint("StartActivityAndCollapseDeprecated")
4042
private fun activityTransfer() {
4143
val intent = Intent(this, TempActivity::class.java)
4244
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK)

android/app/src/main/kotlin/com/follow/clash/services/FlClashVpnService.kt

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ import android.os.Build
1515
import android.os.IBinder
1616
import android.os.Parcel
1717
import android.os.RemoteException
18-
import android.util.Log
1918
import androidx.core.app.NotificationCompat
2019
import com.follow.clash.BaseServiceInterface
2120
import com.follow.clash.GlobalState
2221
import com.follow.clash.MainActivity
2322
import com.follow.clash.R
23+
import com.follow.clash.TempActivity
2424
import com.follow.clash.models.AccessControlMode
2525
import com.follow.clash.models.Props
2626
import com.follow.clash.models.TunProps
@@ -29,7 +29,6 @@ import kotlinx.coroutines.Dispatchers
2929
import kotlinx.coroutines.launch
3030

3131

32-
@SuppressLint("WrongConstant")
3332
class FlClashVpnService : VpnService(), BaseServiceInterface {
3433

3534
companion object {
@@ -73,11 +72,19 @@ class FlClashVpnService : VpnService(), BaseServiceInterface {
7372
override fun start(port: Int, props: Props?): TunProps {
7473
return with(Builder()) {
7574
addAddress(TUN_GATEWAY, TUN_SUBNET_PREFIX)
76-
addAddress(TUN_GATEWAY6, TUN_SUBNET_PREFIX6)
7775
addRoute(NET_ANY, 0)
78-
addRoute(NET_ANY6, 0)
7976
addDnsServer(TUN_DNS)
80-
addDnsServer(TUN_DNS6)
77+
78+
79+
if (props?.ipv6 == true) {
80+
try {
81+
addAddress(TUN_GATEWAY6, TUN_SUBNET_PREFIX6)
82+
addRoute(NET_ANY6, 0)
83+
addDnsServer(TUN_DNS6)
84+
} catch (_: Exception) {
85+
86+
}
87+
}
8188
setMtu(TUN_MTU)
8289
props?.accessControl?.let { accessControl ->
8390
when (accessControl.mode) {
@@ -115,16 +122,16 @@ class FlClashVpnService : VpnService(), BaseServiceInterface {
115122
fd = establish()?.detachFd()
116123
?: throw NullPointerException("Establish VPN rejected by system"),
117124
gateway = "$TUN_GATEWAY/$TUN_SUBNET_PREFIX",
118-
gateway6 = "$TUN_GATEWAY6/$TUN_SUBNET_PREFIX6",
125+
gateway6 = if (props?.ipv6 == true) "$TUN_GATEWAY6/$TUN_SUBNET_PREFIX6" else "",
119126
portal = TUN_PORTAL,
120-
portal6 = TUN_PORTAL6,
127+
portal6 = if (props?.ipv6 == true) TUN_PORTAL6 else "",
121128
dns = TUN_DNS,
122-
dns6 = TUN_DNS6
129+
dns6 = if (props?.ipv6 == true) TUN_DNS6 else ""
123130
)
124131
}
125132
}
126133

127-
fun updateUnderlyingNetworks( networks: Array<Network>){
134+
fun updateUnderlyingNetworks(networks: Array<Network>) {
128135
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
129136
this.setUnderlyingNetworks(networks)
130137
}
@@ -160,18 +167,23 @@ class FlClashVpnService : VpnService(), BaseServiceInterface {
160167
)
161168
}
162169

170+
val stopIntent = Intent(this, TempActivity::class.java)
171+
stopIntent.action = "com.follow.clash.action.STOP"
172+
stopIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_MULTIPLE_TASK)
173+
174+
163175
val stopPendingIntent = if (Build.VERSION.SDK_INT >= 31) {
164176
PendingIntent.getActivity(
165177
this,
166178
0,
167-
Intent("com.follow.clash.action.STOP"),
179+
stopIntent,
168180
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
169181
)
170182
} else {
171183
PendingIntent.getActivity(
172184
this,
173185
0,
174-
Intent("com.follow.clash.action.STOP"),
186+
stopIntent,
175187
PendingIntent.FLAG_UPDATE_CURRENT
176188
)
177189
}

0 commit comments

Comments
 (0)