fix: split tunnel performance improvements
This commit is contained in:
parent
7cf7817cea
commit
dbaf0312f8
|
@ -40,7 +40,7 @@ class AppModule {
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@Provides
|
@Provides
|
||||||
fun provideShortcutManager(@ApplicationContext context: Context): ShortcutManager {
|
fun provideShortcutManager(@ApplicationContext context: Context, @IoDispatcher ioDispatcher: CoroutineDispatcher): ShortcutManager {
|
||||||
return DynamicShortcutManager(context)
|
return DynamicShortcutManager(context, ioDispatcher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,21 @@ import androidx.core.content.pm.ShortcutInfoCompat
|
||||||
import androidx.core.content.pm.ShortcutManagerCompat
|
import androidx.core.content.pm.ShortcutManagerCompat
|
||||||
import androidx.core.graphics.drawable.IconCompat
|
import androidx.core.graphics.drawable.IconCompat
|
||||||
import com.zaneschepke.wireguardautotunnel.R
|
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 {
|
class DynamicShortcutManager(private val context: Context, @IoDispatcher private val ioDispatcher: CoroutineDispatcher) : ShortcutManager {
|
||||||
override fun addShortcuts() {
|
override suspend fun addShortcuts() {
|
||||||
ShortcutManagerCompat.setDynamicShortcuts(context, createShortcuts())
|
withContext(ioDispatcher) {
|
||||||
|
ShortcutManagerCompat.setDynamicShortcuts(context, createShortcuts())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun removeShortcuts() {
|
override suspend fun removeShortcuts() {
|
||||||
ShortcutManagerCompat.removeDynamicShortcuts(context, createShortcuts().map { it.id })
|
withContext(ioDispatcher) {
|
||||||
|
ShortcutManagerCompat.removeDynamicShortcuts(context, createShortcuts().map { it.id })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createShortcuts(): List<ShortcutInfoCompat> {
|
private fun createShortcuts(): List<ShortcutInfoCompat> {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package com.zaneschepke.wireguardautotunnel.service.shortcut
|
package com.zaneschepke.wireguardautotunnel.service.shortcut
|
||||||
|
|
||||||
interface ShortcutManager {
|
interface ShortcutManager {
|
||||||
fun addShortcuts()
|
suspend fun addShortcuts()
|
||||||
fun removeShortcuts()
|
suspend fun removeShortcuts()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.zaneschepke.wireguardautotunnel.ui
|
package com.zaneschepke.wireguardautotunnel.ui
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import com.wireguard.android.backend.WgQuickBackend
|
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.common.snackbar.SnackbarController
|
||||||
import com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.config.model.InterfaceProxy
|
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.config.model.PeerProxy
|
||||||
|
import com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.splittunnel.SplitTunnelApp
|
||||||
import com.zaneschepke.wireguardautotunnel.util.Constants
|
import com.zaneschepke.wireguardautotunnel.util.Constants
|
||||||
import com.zaneschepke.wireguardautotunnel.util.LocaleUtil
|
import com.zaneschepke.wireguardautotunnel.util.LocaleUtil
|
||||||
import com.zaneschepke.wireguardautotunnel.util.StringValue
|
import com.zaneschepke.wireguardautotunnel.util.StringValue
|
||||||
|
import com.zaneschepke.wireguardautotunnel.util.extensions.getAllInternetCapablePackages
|
||||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||||
import kotlinx.coroutines.CoroutineDispatcher
|
import kotlinx.coroutines.CoroutineDispatcher
|
||||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||||
|
@ -64,6 +67,9 @@ constructor(
|
||||||
private val _configurationChange = MutableStateFlow(false)
|
private val _configurationChange = MutableStateFlow(false)
|
||||||
val configurationChange = _configurationChange.asStateFlow()
|
val configurationChange = _configurationChange.asStateFlow()
|
||||||
|
|
||||||
|
private val _splitTunnelApps = MutableStateFlow<List<SplitTunnelApp>>(emptyList())
|
||||||
|
val splitTunnelApps = _splitTunnelApps.asStateFlow()
|
||||||
|
|
||||||
val uiState =
|
val uiState =
|
||||||
combine(
|
combine(
|
||||||
appDataRepository.settings.getSettingsFlow(),
|
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> {
|
suspend fun requestRoot(): Result<Unit> {
|
||||||
return withContext(ioDispatcher) {
|
return withContext(ioDispatcher) {
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
|
|
|
@ -115,6 +115,10 @@ class MainActivity : AppCompatActivity() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
viewModel.getEmitSplitTunnelApps(this@MainActivity)
|
||||||
|
}
|
||||||
|
|
||||||
LaunchedEffect(appUiState.autoTunnelActive) {
|
LaunchedEffect(appUiState.autoTunnelActive) {
|
||||||
requestAutoTunnelTileServiceUpdate()
|
requestAutoTunnelTileServiceUpdate()
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.common.textbox.CustomTextField
|
||||||
import com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.config.model.InterfaceProxy
|
import com.zaneschepke.wireguardautotunnel.ui.screens.tunneloptions.config.model.InterfaceProxy
|
||||||
import com.zaneschepke.wireguardautotunnel.ui.theme.iconSize
|
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.scaledHeight
|
||||||
import com.zaneschepke.wireguardautotunnel.util.extensions.scaledWidth
|
import com.zaneschepke.wireguardautotunnel.util.extensions.scaledWidth
|
||||||
import java.text.Collator
|
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 config by remember { derivedStateOf { appUiState.tunnels.first { it.id == tunnelId } } }
|
||||||
|
|
||||||
|
val splitTunnelApps by viewModel.splitTunnelApps.collectAsStateWithLifecycle()
|
||||||
|
|
||||||
var proxyInterface by remember { mutableStateOf(InterfaceProxy()) }
|
var proxyInterface by remember { mutableStateOf(InterfaceProxy()) }
|
||||||
|
|
||||||
var selectedSplitOption by remember { mutableStateOf(SplitOptions.ALL) }
|
var selectedSplitOption by remember { mutableStateOf(SplitOptions.ALL) }
|
||||||
|
@ -96,27 +97,17 @@ fun SplitTunnelScreen(appUiState: AppUiState, tunnelId: Int, viewModel: AppViewM
|
||||||
selectedPackages.addAll(pair.second)
|
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("") }
|
var query: String by remember { mutableStateOf("") }
|
||||||
|
|
||||||
val sortedPackages by remember {
|
val sortedPackages by remember {
|
||||||
derivedStateOf {
|
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) {
|
LaunchedEffect(Unit) {
|
||||||
// clean up any split tunnel packages for apps that were uninstalled
|
// 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(
|
Scaffold(
|
||||||
|
|
Loading…
Reference in New Issue