Skip to content

Commit 2ae6a73

Browse files
committed
Refresh notification on GOST status changes
1 parent 61ea64f commit 2ae6a73

3 files changed

Lines changed: 30 additions & 15 deletions

File tree

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ android {
1818
applicationId 'com.wsy.pixelproxygateway'
1919
minSdk 29
2020
targetSdk 36
21-
versionCode 4
22-
versionName '1.2.0'
21+
versionCode 5
22+
versionName '1.2.1'
2323
}
2424

2525
signingConfigs {

app/src/main/java/com/wsy/pixelproxygateway/GostProcessManager.kt

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ class GostProcessManager(
1313
context: Context,
1414
private val logStore: LogStore,
1515
private val statusStore: StatusStore,
16+
private val onStatusChanged: () -> Unit = {},
1617
) {
1718
private val appContext = context.applicationContext
1819
private val installer = GostBinaryInstaller(appContext, logStore)
@@ -37,7 +38,7 @@ class GostProcessManager(
3738
return
3839
}
3940
desiredRunning = true
40-
statusStore.update {
41+
updateStatus {
4142
it.copy(
4243
desiredRunning = true,
4344
bindAddress = config.bindAddress,
@@ -69,7 +70,7 @@ class GostProcessManager(
6970
val stopped = stopCurrentProcess(reason)
7071
val current = process
7172
val currentPid = ProcessUtil.pidOf(current)
72-
statusStore.update {
73+
updateStatus {
7374
it.copy(
7475
desiredRunning = false,
7576
proxyRunning = !stopped && current?.isAlive == true,
@@ -90,7 +91,7 @@ class GostProcessManager(
9091
return
9192
}
9293
desiredRunning = true
93-
statusStore.update {
94+
updateStatus {
9495
it.copy(
9596
desiredRunning = true,
9697
startOnBoot = config.startOnBoot,
@@ -116,7 +117,7 @@ class GostProcessManager(
116117
fun markProcessCheck() {
117118
val current = process
118119
val running = current?.isAlive == true
119-
statusStore.update { it.copy(proxyRunning = running, proxyPid = ProcessUtil.pidOf(current)) }
120+
updateStatus { it.copy(proxyRunning = running, proxyPid = ProcessUtil.pidOf(current)) }
120121
if (desiredRunning && !running) {
121122
scheduleRestart("process_watchdog", immediate = false)
122123
}
@@ -129,7 +130,7 @@ class GostProcessManager(
129130
if (current.isAlive) {
130131
val pid = ProcessUtil.pidOf(current)
131132
logStore.append("app", "gost start deferred reason=$reason current_pid=$pid")
132-
statusStore.update {
133+
updateStatus {
133134
it.copy(proxyRunning = true, proxyPid = pid, lastError = "gost still stopping:$reason")
134135
}
135136
if (desiredRunning) scheduleRestart("start_deferred:$reason", immediate = false)
@@ -153,7 +154,7 @@ class GostProcessManager(
153154
process = started
154155
val pid = ProcessUtil.pidOf(started)
155156
logStore.append("app", "gost started pid=$pid reason=$reason")
156-
statusStore.update {
157+
updateStatus {
157158
it.copy(
158159
proxyRunning = true,
159160
proxyPid = pid,
@@ -174,7 +175,7 @@ class GostProcessManager(
174175
}.getOrElse { throwable ->
175176
val message = throwable.message ?: throwable.javaClass.simpleName
176177
logStore.append("app", "gost start failed error=$message")
177-
statusStore.update {
178+
updateStatus {
178179
it.copy(proxyRunning = false, proxyPid = -1, lastError = message)
179180
}
180181
if (desiredRunning) scheduleRestart("start_failed:$message", immediate = false)
@@ -207,7 +208,7 @@ class GostProcessManager(
207208
logStore.append("app", "ignoring stale gost exit pid=$pid code=$exitCode")
208209
return
209210
}
210-
statusStore.update {
211+
updateStatus {
211212
it.copy(
212213
proxyRunning = false,
213214
proxyPid = -1,
@@ -222,7 +223,7 @@ class GostProcessManager(
222223
private fun rejectInvalidStart(error: String, reason: String) {
223224
logStore.append("app", "gost start rejected reason=$reason error=$error")
224225
stop("invalid_config:$reason")
225-
statusStore.update {
226+
updateStatus {
226227
it.copy(
227228
desiredRunning = false,
228229
proxyRunning = false,
@@ -248,7 +249,7 @@ class GostProcessManager(
248249
val delay = next.delaySeconds
249250
restartDelaySeconds = next.nextDelaySeconds
250251
logStore.append("app", "scheduling gost restart reason=$reason delay=${delay}s")
251-
statusStore.update { it.copy(lastRestartReason = reason, lastError = reason) }
252+
updateStatus { it.copy(lastRestartReason = reason, lastError = reason) }
252253
restartFuture = supervisor.schedule({ runScheduledRestart(reason) }, delay, TimeUnit.SECONDS)
253254
}
254255

@@ -299,7 +300,7 @@ class GostProcessManager(
299300
}
300301

301302
logStore.append("app", "gost still alive pid=$pid reason=$reason")
302-
statusStore.update {
303+
updateStatus {
303304
it.copy(proxyRunning = true, proxyPid = pid, lastError = "gost stop timed out:$reason")
304305
}
305306
return false
@@ -327,10 +328,17 @@ class GostProcessManager(
327328
if (remaining.isEmpty()) return true
328329
val message = "untracked gost still running pids=${remaining.joinToString(",")}"
329330
logStore.append("app", "$message reason=$reason")
330-
statusStore.update { it.copy(lastError = message) }
331+
updateStatus { it.copy(lastError = message) }
331332
return false
332333
}
333334

335+
private fun updateStatus(transform: (RuntimeStatus) -> RuntimeStatus): RuntimeStatus {
336+
val next = statusStore.update(transform)
337+
runCatching { onStatusChanged() }
338+
.onFailure { logStore.append("app", "status change callback failed error=${it.message}") }
339+
return next
340+
}
341+
334342
private fun runningGostPids(): List<Long> {
335343
return GOST_PROCESS_NAMES
336344
.flatMap { processName -> pidOf(processName) }

app/src/main/java/com/wsy/pixelproxygateway/ProxyForegroundService.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ class ProxyForegroundService : Service() {
3333
private var wakeLock: PowerManager.WakeLock? = null
3434
private var lastNotificationSnapshot: NotificationSnapshot? = null
3535
private var consecutivePortFailures = 0
36+
@Volatile private var destroying = false
3637
@Volatile private var config = ProxyConfig()
3738

3839
override fun onCreate() {
@@ -41,7 +42,12 @@ class ProxyForegroundService : Service() {
4142
logStore = LogStore(this)
4243
statusStore = StatusStore(this)
4344
statusStore.loadFromDisk()
44-
manager = GostProcessManager(this, logStore, statusStore)
45+
manager = GostProcessManager(
46+
context = this,
47+
logStore = logStore,
48+
statusStore = statusStore,
49+
onStatusChanged = { if (!destroying) updateNotification() },
50+
)
4551
networkChangeRestartMonitor = NetworkChangeRestartMonitor(
4652
context = this,
4753
logStore = logStore,
@@ -488,6 +494,7 @@ class ProxyForegroundService : Service() {
488494
}
489495

490496
override fun onDestroy() {
497+
destroying = true
491498
logStore.append("app", "service destroyed")
492499
statusStore.update { it.copy(serviceRunning = false) }
493500
networkChangeRestartMonitor.stop()

0 commit comments

Comments
 (0)