Skip to content

Commit a498029

Browse files
committed
Load the RuleDatabase separately from the service
1 parent e56f089 commit a498029

File tree

5 files changed

+173
-112
lines changed

5 files changed

+173
-112
lines changed

app/src/main/kotlin/dev/clombardo/dnsnet/Intents.kt

+3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ object Intents {
2828
fun getRestartVpnIntent(): Intent = Intent(applicationContext, AdVpnService::class.java)
2929
.putExtra(AdVpnService.COMMAND_TAG, Command.RESTART.ordinal)
3030

31+
fun getReloadDatabaseIntent(): Intent = Intent(applicationContext, AdVpnService::class.java)
32+
.putExtra(AdVpnService.COMMAND_TAG, Command.RELOAD_DATABASE.ordinal)
33+
3134
fun getMainActivityPendingIntent(): PendingIntent = PendingIntent.getActivity(
3235
applicationContext,
3336
0,

app/src/main/kotlin/dev/clombardo/dnsnet/db/RuleDatabaseUpdateWorker.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class RuleDatabaseUpdateWorker(
9494
val end = System.currentTimeMillis()
9595
logd("doWork: end after ${end - start} milliseconds")
9696

97-
AdVpnService.restart(context)
97+
AdVpnService.reloadDatabase(context)
9898

9999
postExecute()
100100

app/src/main/kotlin/dev/clombardo/dnsnet/vpn/AdVpnService.kt

+43-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import androidx.annotation.StringRes
3434
import androidx.core.app.NotificationCompat
3535
import androidx.core.content.ContextCompat
3636
import dev.clombardo.dnsnet.DnsNetApplication.Companion.applicationContext
37+
import dev.clombardo.dnsnet.FileHelper
3738
import dev.clombardo.dnsnet.Intents
3839
import dev.clombardo.dnsnet.MainActivity
3940
import dev.clombardo.dnsnet.NotificationChannels
@@ -44,10 +45,15 @@ import dev.clombardo.dnsnet.logd
4445
import dev.clombardo.dnsnet.logi
4546
import dev.clombardo.dnsnet.logw
4647
import dev.clombardo.dnsnet.vpn.VpnStatus.Companion.toVpnStatus
48+
import kotlinx.atomicfu.atomic
49+
import kotlinx.coroutines.CoroutineScope
50+
import kotlinx.coroutines.Dispatchers
4751
import kotlinx.coroutines.flow.MutableStateFlow
4852
import kotlinx.coroutines.flow.asStateFlow
53+
import kotlinx.coroutines.launch
4954
import uniffi.net.AdVpnCallback
5055
import uniffi.net.RuleDatabase
56+
import uniffi.net.RuleDatabaseController
5157

5258
enum class VpnStatus {
5359
STARTING,
@@ -81,6 +87,7 @@ enum class Command {
8187
PAUSE,
8288
RESUME,
8389
RESTART,
90+
RELOAD_DATABASE,
8491
}
8592

8693
class AdVpnService : VpnService(), Handler.Callback, AdVpnCallback {
@@ -147,6 +154,15 @@ class AdVpnService : VpnService(), Handler.Callback, AdVpnCallback {
147154
ContextCompat.startForegroundService(context, Intents.getRestartVpnIntent())
148155
}
149156

157+
fun reloadDatabase(context: Context) {
158+
if (!isRunning()) {
159+
logw("VPN is stopped, cannot reload database")
160+
return
161+
}
162+
163+
context.startService(Intents.getReloadDatabaseIntent())
164+
}
165+
150166
private fun getOpenMainActivityPendingIntent() = PendingIntent.getActivity(
151167
applicationContext,
152168
0,
@@ -176,7 +192,28 @@ class AdVpnService : VpnService(), Handler.Callback, AdVpnCallback {
176192

177193
private val handler = Handler(Looper.myLooper()!!, this)
178194

179-
private val ruleDatabase = RuleDatabase()
195+
// Guard against multiple coroutines waiting to reload the database
196+
private val reloadPending = atomic(false)
197+
private val ruleDatabaseController = RuleDatabaseController()
198+
private val ruleDatabase = RuleDatabase(controller = ruleDatabaseController).also {
199+
it.reload()
200+
}
201+
202+
fun RuleDatabase.reload() {
203+
if (reloadPending.getAndSet(true)) {
204+
return
205+
}
206+
207+
CoroutineScope(Dispatchers.IO).launch {
208+
waitOnInit()
209+
reloadPending.getAndSet(false)
210+
initialize(
211+
androidFileHelper = FileHelper,
212+
hostItems = config.hosts.items.map { it.toNative() },
213+
hostExceptions = config.hosts.exceptions.map { it.toNative() },
214+
)
215+
}
216+
}
180217

181218
private val vpnThread = AdVpnThread(
182219
adVpnService = this,
@@ -457,6 +494,10 @@ class AdVpnService : VpnService(), Handler.Callback, AdVpnCallback {
457494
Command.PAUSE -> pauseVpn()
458495

459496
Command.RESTART -> restartVpnThread()
497+
498+
Command.RELOAD_DATABASE -> {
499+
ruleDatabase.reload()
500+
}
460501
}
461502

462503
return START_STICKY
@@ -618,6 +659,7 @@ class AdVpnService : VpnService(), Handler.Callback, AdVpnCallback {
618659

619660
override fun onDestroy() {
620661
logi("Destroyed, shutting down")
662+
ruleDatabaseController.setShouldStop(true)
621663
stopVpn()
622664
}
623665

app/src/main/kotlin/dev/clombardo/dnsnet/vpn/AdVpnThread.kt

+1-11
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,14 @@ import android.os.ParcelFileDescriptor
3434
import android.system.OsConstants
3535
import dev.clombardo.dnsnet.Configuration
3636
import dev.clombardo.dnsnet.DnsNetApplication.Companion.applicationContext
37-
import dev.clombardo.dnsnet.FileHelper
3837
import dev.clombardo.dnsnet.MainActivity
3938
import dev.clombardo.dnsnet.R
4039
import dev.clombardo.dnsnet.config
4140
import dev.clombardo.dnsnet.logd
4241
import dev.clombardo.dnsnet.loge
4342
import dev.clombardo.dnsnet.logi
4443
import dev.clombardo.dnsnet.logw
45-
import kotlinx.atomicfu.atomic
46-
import kotlinx.coroutines.Dispatchers
47-
import kotlinx.coroutines.withContext
4844
import uniffi.net.BlockLoggerCallback
49-
import uniffi.net.NativeHost
5045
import uniffi.net.RuleDatabase
5146
import uniffi.net.VpnController
5247
import uniffi.net.VpnException
@@ -158,12 +153,7 @@ class AdVpnThread(
158153
override fun run() {
159154
logi("Starting")
160155

161-
ruleDatabase.initialize(
162-
androidFileHelper = FileHelper,
163-
vpnController = threadData?.vpnController ?: throw IllegalStateException(),
164-
hostItems = config.hosts.items.map { it.toNative() },
165-
hostExceptions = config.hosts.exceptions.map { it.toNative() },
166-
)
156+
ruleDatabase.waitOnInit()
167157

168158
var retryTimeout = MIN_RETRY_TIME
169159
// Try connecting the vpn continuously

0 commit comments

Comments
 (0)