fix: split tunnel performance improvements

This commit is contained in:
Zane Schepke 2024-12-22 02:11:42 -05:00
parent 7cf7817cea
commit dbaf0312f8
6 changed files with 43 additions and 22 deletions

View File

@ -40,7 +40,7 @@ class AppModule {
@Singleton
@Provides
fun provideShortcutManager(@ApplicationContext context: Context): ShortcutManager {
return DynamicShortcutManager(context)
fun provideShortcutManager(@ApplicationContext context: Context, @IoDispatcher ioDispatcher: CoroutineDispatcher): ShortcutManager {
return DynamicShortcutManager(context, ioDispatcher)
}
}

View File

@ -6,14 +6,21 @@ import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.drawable.IconCompat
import com.zaneschepke.wireguardautotunnel.R
import com.zaneschepke.wireguardautotunnel.module.IoDispatcher
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.withContext
class DynamicShortcutManager(private val context: Context) : ShortcutManager {
override fun addShortcuts() {
ShortcutManagerCompat.setDynamicShortcuts(context, createShortcuts())
class DynamicShortcutManager(private val context: Context, @IoDispatcher private val ioDispatcher: CoroutineDispatcher) : ShortcutManager {
override suspend fun addShortcuts() {
withContext(ioDispatcher) {
ShortcutManagerCompat.setDynamicShortcuts(context, createShortcuts())
}
}
override fun removeShortcuts() {
ShortcutManagerCompat.removeDynamicShortcuts(context, createShortcuts().map { it.id })
override suspend fun removeShortcuts() {
withContext(ioDispatcher) {
ShortcutManagerCompat.removeDynamicShortcuts(context, createShortcuts().map { it.id })
}
}
private fun createShortcuts(): List<ShortcutInfoCompat> {

View File

@ -1,6 +1,6 @@
package com.zaneschepke.wireguardautotunnel.service.shortcut
interface ShortcutManager {
fun addShortcuts()
fun removeShortcuts()
suspend fun addShortcuts()
suspend fun removeShortcuts()
}

View File

@ -1,5 +1,6 @@
package com.zaneschepke.wireguardautotunnel.ui
import android.content.Context
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.wireguard.android.backend.WgQuickBackend
@ -19,9 +20,11 @@ import com.zaneschepke.wireguardautotunnel.service.tunnel.TunnelState
import com.zaneschepke.wireguardautotunnel.ui.common.snackbar.SnackbarController
import com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.config.model.InterfaceProxy
import com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.config.model.PeerProxy
import com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.splittunnel.SplitTunnelApp
import com.zaneschepke.wireguardautotunnel.util.Constants
import com.zaneschepke.wireguardautotunnel.util.LocaleUtil
import com.zaneschepke.wireguardautotunnel.util.StringValue
import com.zaneschepke.wireguardautotunnel.util.extensions.getAllInternetCapablePackages
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.MutableSharedFlow
@ -64,6 +67,9 @@ constructor(
private val _configurationChange = MutableStateFlow(false)
val configurationChange = _configurationChange.asStateFlow()
private val _splitTunnelApps = MutableStateFlow<List<SplitTunnelApp>>(emptyList())
val splitTunnelApps = _splitTunnelApps.asStateFlow()
val uiState =
combine(
appDataRepository.settings.getSettingsFlow(),
@ -267,6 +273,19 @@ constructor(
}
}
suspend fun getEmitSplitTunnelApps(context: Context) {
withContext(ioDispatcher) {
val apps = context.getAllInternetCapablePackages().filter { it.applicationInfo != null }.map { pack ->
SplitTunnelApp(
context.packageManager.getApplicationIcon(pack.applicationInfo!!),
context.packageManager.getApplicationLabel(pack.applicationInfo!!).toString(),
pack.packageName,
)
}
_splitTunnelApps.emit(apps)
}
}
suspend fun requestRoot(): Result<Unit> {
return withContext(ioDispatcher) {
kotlin.runCatching {

View File

@ -115,6 +115,10 @@ class MainActivity : AppCompatActivity() {
}
}
LaunchedEffect(Unit) {
viewModel.getEmitSplitTunnelApps(this@MainActivity)
}
LaunchedEffect(appUiState.autoTunnelActive) {
requestAutoTunnelTileServiceUpdate()
}

View File

@ -56,7 +56,6 @@ import com.zaneschepke.wireguardautotunnel.ui.common.navigation.TopNavBar
import com.zaneschepke.wireguardautotunnel.ui.common.textbox.CustomTextField
import com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.config.model.InterfaceProxy
import com.zaneschepke.wireguardautotunnel.ui.theme.iconSize
import com.zaneschepke.wireguardautotunnel.util.extensions.getAllInternetCapablePackages
import com.zaneschepke.wireguardautotunnel.util.extensions.scaledHeight
import com.zaneschepke.wireguardautotunnel.util.extensions.scaledWidth
import java.text.Collator
@ -79,6 +78,8 @@ fun SplitTunnelScreen(appUiState: AppUiState, tunnelId: Int, viewModel: AppViewM
val config by remember { derivedStateOf { appUiState.tunnels.first { it.id == tunnelId } } }
val splitTunnelApps by viewModel.splitTunnelApps.collectAsStateWithLifecycle()
var proxyInterface by remember { mutableStateOf(InterfaceProxy()) }
var selectedSplitOption by remember { mutableStateOf(SplitOptions.ALL) }
@ -96,27 +97,17 @@ fun SplitTunnelScreen(appUiState: AppUiState, tunnelId: Int, viewModel: AppViewM
selectedPackages.addAll(pair.second)
}
val packages = remember {
context.getAllInternetCapablePackages().filter { it.applicationInfo != null }.map { pack ->
SplitTunnelApp(
context.packageManager.getApplicationIcon(pack.applicationInfo!!),
context.packageManager.getApplicationLabel(pack.applicationInfo!!).toString(),
pack.packageName,
)
}
}
var query: String by remember { mutableStateOf("") }
val sortedPackages by remember {
derivedStateOf {
packages.sortedWith(compareBy(collator) { it.name }).filter { it.name.contains(query) }.toMutableStateList()
splitTunnelApps.sortedWith(compareBy(collator) { it.name }).filter { it.name.contains(query) }.toMutableStateList()
}
}
LaunchedEffect(Unit) {
// clean up any split tunnel packages for apps that were uninstalled
viewModel.cleanUpUninstalledApps(config, packages.map { it.`package` })
viewModel.cleanUpUninstalledApps(config, splitTunnelApps.map { it.`package` })
}
Scaffold(