Skip to content

Commit d7a088e

Browse files
committed
Support override script
Support proxies search Add some scenes auto close connections Update core Optimize more details
1 parent 76c9f08 commit d7a088e

File tree

172 files changed

+8715
-5765
lines changed

Some content is hidden

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

172 files changed

+8715
-5765
lines changed

.github/workflows/build.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,20 @@ jobs:
6363
cache-dependency-path: |
6464
core/go.sum
6565
66+
- name: Setup Flutter Master
67+
if: startsWith(matrix.os, 'windows-11-arm') || startsWith(matrix.os, 'ubuntu-24.04-arm')
68+
uses: subosito/flutter-action@v2
69+
with:
70+
channel: 'master'
71+
cache: true
72+
6673
- name: Setup Flutter
74+
if: !(startsWith(matrix.os, 'windows-11-arm') || startsWith(matrix.os, 'ubuntu-24.04-arm'))
6775
uses: subosito/flutter-action@v2
6876
with:
69-
channel: ${{ (startsWith(matrix.os, 'windows-11-arm') || startsWith(matrix.os, 'ubuntu-24.04-arm')) && 'master' || 'stable' }}
77+
channel: 'stable'
7078
cache: true
79+
flutter-version: 3.29.3
7180

7281
- name: Get Flutter Dependency
7382
run: flutter pub get

android/app/build.gradle

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

android/app/build.gradle.kts

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import java.util.Properties
2+
3+
plugins {
4+
id("com.android.application")
5+
id("kotlin-android")
6+
id("dev.flutter.flutter-gradle-plugin")
7+
}
8+
9+
val localPropertiesFile = rootProject.file("local.properties")
10+
val localProperties = Properties().apply {
11+
if (localPropertiesFile.exists()) {
12+
localPropertiesFile.inputStream().use { load(it) }
13+
}
14+
}
15+
16+
val mStoreFile: File = file("keystore.jks")
17+
val mStorePassword: String? = localProperties.getProperty("storePassword")
18+
val mKeyAlias: String? = localProperties.getProperty("keyAlias")
19+
val mKeyPassword: String? = localProperties.getProperty("keyPassword")
20+
val isRelease = mStoreFile.exists()
21+
&& mStorePassword != null
22+
&& mKeyAlias != null
23+
&& mKeyPassword != null
24+
25+
android {
26+
namespace = "com.follow.clash"
27+
compileSdk = 35
28+
ndkVersion = "28.0.13004108"
29+
30+
compileOptions {
31+
sourceCompatibility = JavaVersion.VERSION_17
32+
targetCompatibility = JavaVersion.VERSION_17
33+
}
34+
35+
kotlinOptions {
36+
jvmTarget = JavaVersion.VERSION_17.toString()
37+
}
38+
39+
defaultConfig {
40+
applicationId = "com.follow.clash"
41+
minSdk = flutter.minSdkVersion
42+
targetSdk = flutter.targetSdkVersion
43+
versionCode = flutter.versionCode
44+
versionName = flutter.versionName
45+
}
46+
47+
signingConfigs {
48+
if (isRelease) {
49+
create("release") {
50+
storeFile = mStoreFile
51+
storePassword = mStorePassword
52+
keyAlias = mKeyAlias
53+
keyPassword = mKeyPassword
54+
}
55+
}
56+
}
57+
58+
buildTypes {
59+
debug {
60+
isMinifyEnabled = false
61+
applicationIdSuffix = ".debug"
62+
}
63+
64+
release {
65+
isMinifyEnabled = true
66+
isDebuggable = false
67+
68+
signingConfig = if (isRelease) {
69+
signingConfigs.getByName("release")
70+
} else {
71+
signingConfigs.getByName("debug")
72+
}
73+
74+
proguardFiles(
75+
getDefaultProguardFile("proguard-android-optimize.txt"),
76+
"proguard-rules.pro"
77+
)
78+
}
79+
}
80+
}
81+
82+
flutter {
83+
source = "../.."
84+
}
85+
86+
dependencies {
87+
implementation(project(":core"))
88+
implementation("androidx.core:core-splashscreen:1.0.1")
89+
implementation("com.google.code.gson:gson:2.10.1")
90+
implementation("com.android.tools.smali:smali-dexlib2:3.0.9") {
91+
exclude(group = "com.google.guava", module = "guava")
92+
}
93+
}

android/app/src/main/AndroidManifest.xml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@
77
<uses-feature
88
android:name="android.hardware.camera"
99
android:required="false" />
10+
<uses-feature
11+
android:name="android.software.leanback"
12+
android:required="false" />
1013

1114
<uses-permission android:name="android.permission.INTERNET" />
1215
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
@@ -22,6 +25,7 @@
2225

2326
<application
2427
android:name=".FlClashApplication"
28+
android:banner="@mipmap/ic_banner"
2529
android:hardwareAccelerated="true"
2630
android:icon="@mipmap/ic_launcher"
2731
android:label="FlClash">
@@ -88,7 +92,7 @@
8892
<service
8993
android:name=".services.FlClashTileService"
9094
android:exported="true"
91-
android:icon="@drawable/ic_stat_name"
95+
android:icon="@drawable/ic"
9296
android:label="FlClash"
9397
android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"
9498
tools:targetApi="n">

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ import com.follow.clash.plugins.VpnPlugin
77
import io.flutter.FlutterInjector
88
import io.flutter.embedding.engine.FlutterEngine
99
import io.flutter.embedding.engine.dart.DartExecutor
10+
import kotlinx.coroutines.CoroutineScope
11+
import kotlinx.coroutines.Dispatchers
12+
import kotlinx.coroutines.launch
13+
import kotlinx.coroutines.withContext
1014
import java.util.concurrent.locks.ReentrantLock
1115
import kotlin.concurrent.withLock
1216

@@ -33,6 +37,15 @@ object GlobalState {
3337
return currentEngine?.plugins?.get(AppPlugin::class.java) as AppPlugin?
3438
}
3539

40+
fun syncStatus() {
41+
CoroutineScope(Dispatchers.Default).launch {
42+
val status = getCurrentVPNPlugin()?.getStatus() ?: false
43+
withContext(Dispatchers.Main){
44+
runState.value = if (status) RunState.START else RunState.STOP
45+
}
46+
}
47+
}
48+
3649
suspend fun getText(text: String): String {
3750
return getCurrentAppPlugin()?.getText(text) ?: ""
3851
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class MainActivity : FlutterActivity() {
1717

1818
override fun onDestroy() {
1919
GlobalState.flutterEngine = null
20+
GlobalState.runState.value = RunState.STOP
2021
super.onDestroy()
2122
}
2223
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ data object ServicePlugin : FlutterPlugin, MethodChannel.MethodCallHandler {
5151
}
5252
}
5353

54+
5455
private fun handleDestroy() {
5556
GlobalState.destroyServiceEngine()
5657
}

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,13 @@ data object VpnPlugin : FlutterPlugin, MethodChannel.MethodCallHandler {
200200
timerJob = null
201201
}
202202

203+
204+
suspend fun getStatus(): Boolean? {
205+
return withContext(Dispatchers.Default) {
206+
flutterMethodChannel.awaitResult<Boolean>("status", null)
207+
}
208+
}
209+
203210
private fun handleStartService() {
204211
if (flClashService == null) {
205212
bindService()
@@ -248,9 +255,9 @@ data object VpnPlugin : FlutterPlugin, MethodChannel.MethodCallHandler {
248255
GlobalState.runLock.withLock {
249256
if (GlobalState.runState.value == RunState.STOP) return
250257
GlobalState.runState.value = RunState.STOP
258+
flClashService?.stop()
251259
stopForegroundJob()
252260
Core.stopTun()
253-
flClashService?.stop()
254261
GlobalState.handleTryDestroy()
255262
}
256263
}

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import com.follow.clash.MainActivity
1616
import com.follow.clash.R
1717
import com.follow.clash.extensions.getActionPendingIntent
1818
import com.follow.clash.models.VpnOptions
19-
import io.flutter.Log
2019
import kotlinx.coroutines.CoroutineScope
2120
import kotlinx.coroutines.Deferred
2221
import kotlinx.coroutines.Dispatchers
@@ -54,7 +53,7 @@ fun Service.createFlClashNotificationBuilder(): Deferred<NotificationCompat.Buil
5453
this@createFlClashNotificationBuilder, GlobalState.NOTIFICATION_CHANNEL
5554
)
5655
) {
57-
setSmallIcon(R.drawable.ic_stat_name)
56+
setSmallIcon(R.drawable.ic)
5857
setContentTitle("FlClash")
5958
setContentIntent(pendingIntent)
6059
setCategory(NotificationCompat.CATEGORY_SERVICE)
@@ -76,9 +75,8 @@ fun Service.startForeground(notification: Notification) {
7675
val manager = getSystemService(NotificationManager::class.java)
7776
var channel = manager?.getNotificationChannel(GlobalState.NOTIFICATION_CHANNEL)
7877
if (channel == null) {
79-
Log.d("[FlClash]","createNotificationChannel===>")
8078
channel = NotificationChannel(
81-
GlobalState.NOTIFICATION_CHANNEL, "FlClash", NotificationManager.IMPORTANCE_LOW
79+
GlobalState.NOTIFICATION_CHANNEL, "SERVICE_CHANNEL", NotificationManager.IMPORTANCE_LOW
8280
)
8381
manager?.createNotificationChannel(channel)
8482
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class FlClashTileService : TileService() {
3333

3434
override fun onStartListening() {
3535
super.onStartListening()
36+
GlobalState.syncStatus()
3637
GlobalState.runState.value?.let { updateTile(it) }
3738
GlobalState.runState.observeForever(observer)
3839
}

0 commit comments

Comments
 (0)