mirror of
https://github.com/wgtunnel/android.git
synced 2026-07-03 14:07:49 +02:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6f48147b3e | |||
| 16979dbb2b | |||
| 5d8190628d | |||
| 6d597a235d | |||
| 61fd2f01b9 | |||
| 914a641977 | |||
| c97a3afbc4 | |||
| fadc2d1562 | |||
| 106ab76b82 | |||
| 48b3f60b37 | |||
| e7f5cee6dd | |||
| 5e01fd6c85 | |||
| dcbd72c6f6 | |||
| f27aa1452a | |||
| 82c3521c58 | |||
| c6535ffe7e | |||
| be5fe94ce6 | |||
| 1e905c1cfb | |||
| a549c111aa | |||
| 5ab344044e | |||
| 7030f68548 | |||
| ecd51b6fe5 | |||
| 3e4f8e0791 | |||
| e940a0dbc5 | |||
| 8e233475df | |||
| 24789826ad | |||
| 787e0d1a71 | |||
| 914ef53ef0 | |||
| a569974beb | |||
| 87bc89b6f1 | |||
| c343220e96 | |||
| 5447ec73f7 | |||
| a2b8eb5b0b | |||
| e37777e662 | |||
| ee3fcabcf1 | |||
| 2a8895ffbc | |||
| b1fdb5b9b2 |
@@ -0,0 +1,22 @@
|
||||
# Contributor Code of Conduct
|
||||
|
||||
## Pledge
|
||||
|
||||
We as individuals involved in this project, pledge to participate in this
|
||||
community in a respectful, constructive, and civil manner as we work towards a common goal
|
||||
of delivering free, open source, and value adding software for all.
|
||||
|
||||
## Standard
|
||||
|
||||
The standard for this community is the Golden Rule.
|
||||
|
||||
> “Do unto others as you would have them do unto you.”
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies to all spaces related to WG Tunnel.
|
||||
|
||||
## Incidents or Concerns
|
||||
|
||||
For any incidents or concerns, reach out to Zane at
|
||||
<support@zaneschepke.com>.
|
||||
@@ -89,6 +89,32 @@ jobs:
|
||||
draft: false
|
||||
prerelease: true
|
||||
files: ${{ github.workspace }}/${{ steps.apk-path.outputs.path }}
|
||||
|
||||
- name: Install apksigner
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y apksigner
|
||||
|
||||
- name: Get checksum
|
||||
id: checksum
|
||||
run: echo "checksum=$(apksigner verify -print-certs ${{ steps.apk-path.outputs.path }} | grep -Po "(?<=SHA-256 digest:) .*" | tr -d "[:blank:]")" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Append checksum
|
||||
id: append_checksum
|
||||
uses: softprops/action-gh-release@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
body: |
|
||||
|
||||
SHA256 fingerprint:
|
||||
```${{ steps.checksum.outputs.checksum }}```
|
||||
tag_name: ${{ github.ref_name }}
|
||||
name: ${{ github.ref_name }}
|
||||
draft: false
|
||||
prerelease: true
|
||||
append_body: true
|
||||
|
||||
- name: Deploy with fastlane
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
|
||||
@@ -95,6 +95,32 @@ jobs:
|
||||
draft: false
|
||||
prerelease: false
|
||||
files: ${{ github.workspace }}/${{ steps.apk-path.outputs.path }}
|
||||
|
||||
- name: Install apksigner
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y apksigner
|
||||
|
||||
- name: Get checksum
|
||||
id: checksum
|
||||
run: echo "checksum=$(apksigner verify -print-certs ${{ steps.apk-path.outputs.path }} | grep -Po "(?<=SHA-256 digest:) .*" | tr -d "[:blank:]")" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Append checksum
|
||||
id: append_checksum
|
||||
uses: softprops/action-gh-release@v2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
body: |
|
||||
|
||||
SHA256 fingerprint:
|
||||
```${{ steps.checksum.outputs.checksum }}```
|
||||
tag_name: ${{ github.ref_name }}
|
||||
name: ${{ github.ref_name }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
append_body: true
|
||||
|
||||
- name: Deploy with fastlane
|
||||
uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
|
||||
@@ -4,8 +4,9 @@ WG Tunnel
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
[](https://discord.gg/rbRRNh6H7V)
|
||||
[](https://discord.gg/rbRRNh6H7V)
|
||||
[](https://twitter.com/i/communities/1780655267685736818)
|
||||
[](https://t.me/wgtunnel)
|
||||
|
||||
</div>
|
||||
|
||||
@@ -49,24 +50,40 @@ and on while on different networks. This app was created to offer a free solutio
|
||||
## Features
|
||||
|
||||
* Add tunnels via .conf file, zip, manual entry, or QR code
|
||||
* Auto connect to VPN based on Wi-Fi SSID, ethernet, or mobile data
|
||||
* Auto connect to tunnels based on Wi-Fi SSID, ethernet, or mobile data
|
||||
* Split tunneling by application with search
|
||||
* WireGuard support for kernel and userspace modes
|
||||
* Always-On VPN support
|
||||
* Export tunnels to zip
|
||||
* Quick tile support for VPN toggling
|
||||
* Static shortcuts support for primary tunnel for automation integration
|
||||
* Quick tile support for tunnel toggling, auto-tunneling
|
||||
* Static shortcuts support for tunnel toggling, auto-tunneling
|
||||
* Intent automation support for all tunnels
|
||||
* Automatic service restart after reboot
|
||||
* Automatic auto-tunneling service restart after reboot
|
||||
* Automatic tunnel restart after reboot
|
||||
* Battery preservation measures
|
||||
* Restart tunnel on ping failure (beta)
|
||||
|
||||
## Docs (WIP)
|
||||
## Docs
|
||||
|
||||
Basic documentation of the feature and behaviors of this app can be
|
||||
found [here](https://zaneschepke.com/wgtunnel-docs/overview.html).
|
||||
|
||||
The repository for these docs can be found [here](https://github.com/zaneschepke/wgtunnel-docs).
|
||||
|
||||
## Contributing
|
||||
|
||||
Any contributions in the form of feedback, issues, code, or translations are welcome and much appreciated!
|
||||
|
||||
Please read the [code of conduct](https://github.com/zaneschepke/wgtunnel?tab=coc-ov-file#contributor-code-of-conduct) before contributing.
|
||||
|
||||
## Translation
|
||||
|
||||
This app is using [Weblate](https://weblate.org) to assist with translations.
|
||||
|
||||
Help translate WG Tunnel into your language at [Hosted Weblate](https://hosted.weblate.org/engage/wg-tunnel/).\
|
||||
[](https://hosted.weblate.org/engage/wg-tunnel/)
|
||||
|
||||
|
||||
## Building
|
||||
|
||||
```
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
# Security Policy
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please report security issues to `support@zaneschepke.com`
|
||||
@@ -12,6 +12,10 @@ android {
|
||||
namespace = Constants.APP_ID
|
||||
compileSdk = Constants.TARGET_SDK
|
||||
|
||||
androidResources {
|
||||
generateLocaleConfig = true
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId = Constants.APP_ID
|
||||
minSdk = Constants.MIN_SDK
|
||||
@@ -25,8 +29,6 @@ android {
|
||||
getByName("debug").assets.srcDirs(files("$projectDir/schemas")) // Room
|
||||
}
|
||||
|
||||
resourceConfigurations.addAll(listOf("en"))
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
vectorDrawables { useSupportLibrary = true }
|
||||
}
|
||||
@@ -158,8 +160,8 @@ dependencies {
|
||||
debugImplementation(libs.androidx.compose.ui.tooling)
|
||||
debugImplementation(libs.androidx.compose.manifest)
|
||||
|
||||
// get tunnel lib from github packages or mavenLocal
|
||||
implementation(libs.tunnel)
|
||||
// tunnel
|
||||
implementation(libs.amneziawg.android)
|
||||
coreLibraryDesugaring(libs.desugar.jdk.libs)
|
||||
|
||||
// logging
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
<application
|
||||
android:name=".WireGuardAutoTunnel"
|
||||
android:allowBackup="true"
|
||||
android:banner="@mipmap/ic_banner"
|
||||
android:banner="@drawable/ic_banner"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
android:fullBackupContent="@xml/backup_rules"
|
||||
|
||||
@@ -4,7 +4,7 @@ import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.Index
|
||||
import androidx.room.PrimaryKey
|
||||
import com.wireguard.config.Config
|
||||
import org.amnezia.awg.config.Config
|
||||
import java.io.InputStream
|
||||
|
||||
@Entity(indices = [Index(value = ["name"], unique = true)])
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
package com.zaneschepke.wireguardautotunnel.module
|
||||
|
||||
import android.content.Context
|
||||
import com.wireguard.android.backend.Backend
|
||||
import com.wireguard.android.backend.GoBackend
|
||||
import com.wireguard.android.backend.WgQuickBackend
|
||||
import com.wireguard.android.util.RootShell
|
||||
import com.wireguard.android.util.ToolsInstaller
|
||||
import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository
|
||||
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
|
||||
import com.zaneschepke.wireguardautotunnel.service.tunnel.VpnService
|
||||
@@ -15,6 +10,11 @@ import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import org.amnezia.awg.backend.AwgQuickBackend
|
||||
import org.amnezia.awg.backend.Backend
|
||||
import org.amnezia.awg.backend.GoBackend
|
||||
import org.amnezia.awg.util.RootShell
|
||||
import org.amnezia.awg.util.ToolsInstaller
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@@ -37,7 +37,7 @@ class TunnelModule {
|
||||
@Singleton
|
||||
@Kernel
|
||||
fun provideKernelBackend(@ApplicationContext context: Context, rootShell: RootShell): Backend {
|
||||
return WgQuickBackend(context, rootShell, ToolsInstaller(context, rootShell))
|
||||
return AwgQuickBackend(context, rootShell, ToolsInstaller(context, rootShell))
|
||||
}
|
||||
|
||||
@Provides
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ class NotificationActionReceiver : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent?) = goAsync {
|
||||
try {
|
||||
//TODO fix for manual start changes when enabled
|
||||
serviceManager.stopVpnService(context)
|
||||
serviceManager.stopVpnServiceForeground(context)
|
||||
delay(Constants.TOGGLE_TUNNEL_DELAY)
|
||||
serviceManager.startVpnServiceForeground(context)
|
||||
} catch (e: Exception) {
|
||||
|
||||
@@ -3,5 +3,6 @@ package com.zaneschepke.wireguardautotunnel.service.foreground
|
||||
enum class Action {
|
||||
START,
|
||||
START_FOREGROUND,
|
||||
STOP
|
||||
STOP,
|
||||
STOP_FOREGROUND
|
||||
}
|
||||
|
||||
+4
-15
@@ -24,8 +24,7 @@ open class ForegroundService : LifecycleService() {
|
||||
when (action) {
|
||||
Action.START.name,
|
||||
Action.START_FOREGROUND.name -> startService(intent.extras)
|
||||
|
||||
Action.STOP.name -> stopService(intent.extras)
|
||||
Action.STOP.name, Action.STOP_FOREGROUND.name -> stopService()
|
||||
Constants.ALWAYS_ON_VPN_ACTION -> {
|
||||
Timber.i("Always-on VPN starting service")
|
||||
startService(intent.extras)
|
||||
@@ -38,29 +37,19 @@ open class ForegroundService : LifecycleService() {
|
||||
"with a null intent. It has been probably restarted by the system.",
|
||||
)
|
||||
}
|
||||
// by returning this we make sure the service is restarted if the system kills the service
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
Timber.d("The service has been destroyed")
|
||||
}
|
||||
|
||||
protected open fun startService(extras: Bundle?) {
|
||||
if (isServiceStarted) return
|
||||
Timber.d("Starting ${this.javaClass.simpleName}")
|
||||
isServiceStarted = true
|
||||
}
|
||||
|
||||
protected open fun stopService(extras: Bundle?) {
|
||||
protected open fun stopService() {
|
||||
Timber.d("Stopping ${this.javaClass.simpleName}")
|
||||
try {
|
||||
stopForeground(STOP_FOREGROUND_REMOVE)
|
||||
stopSelf()
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e)
|
||||
}
|
||||
stopForeground(STOP_FOREGROUND_REMOVE)
|
||||
stopSelf()
|
||||
isServiceStarted = false
|
||||
}
|
||||
}
|
||||
|
||||
+13
-10
@@ -23,15 +23,8 @@ class ServiceManager(private val appDataRepository: AppDataRepository) {
|
||||
intent.component?.javaClass
|
||||
try {
|
||||
when (action) {
|
||||
Action.START_FOREGROUND -> {
|
||||
context.startForegroundService(intent)
|
||||
}
|
||||
|
||||
Action.START -> {
|
||||
context.startService(intent)
|
||||
}
|
||||
|
||||
Action.STOP -> context.startService(intent)
|
||||
Action.START_FOREGROUND, Action.STOP_FOREGROUND -> context.startForegroundService(intent)
|
||||
Action.START, Action.STOP -> context.startService(intent)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
Timber.e(e.message)
|
||||
@@ -52,9 +45,19 @@ class ServiceManager(private val appDataRepository: AppDataRepository) {
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun stopVpnServiceForeground(context: Context, isManualStop: Boolean = false) {
|
||||
if (isManualStop) onManualStop()
|
||||
Timber.i("Stopping vpn service")
|
||||
actionOnService(
|
||||
Action.STOP_FOREGROUND,
|
||||
context,
|
||||
WireGuardTunnelService::class.java,
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun stopVpnService(context: Context, isManualStop: Boolean = false) {
|
||||
if (isManualStop) onManualStop()
|
||||
Timber.d("Stopping vpn service action")
|
||||
Timber.i("Stopping vpn service")
|
||||
actionOnService(
|
||||
Action.STOP,
|
||||
context,
|
||||
|
||||
-6
@@ -1,6 +0,0 @@
|
||||
package com.zaneschepke.wireguardautotunnel.service.foreground
|
||||
|
||||
enum class ServiceState {
|
||||
STARTED,
|
||||
STOPPED,
|
||||
}
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
package com.zaneschepke.wireguardautotunnel.service.foreground
|
||||
|
||||
import com.wireguard.android.backend.Tunnel
|
||||
import com.zaneschepke.wireguardautotunnel.data.model.Settings
|
||||
import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig
|
||||
import org.amnezia.awg.backend.Tunnel
|
||||
|
||||
data class WatcherState(
|
||||
val isWifiConnected: Boolean = false,
|
||||
|
||||
+17
-12
@@ -5,7 +5,6 @@ import android.os.Bundle
|
||||
import android.os.PowerManager
|
||||
import androidx.core.app.ServiceCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.wireguard.android.backend.Tunnel
|
||||
import com.zaneschepke.wireguardautotunnel.R
|
||||
import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig
|
||||
import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository
|
||||
@@ -18,12 +17,14 @@ import com.zaneschepke.wireguardautotunnel.service.notification.NotificationServ
|
||||
import com.zaneschepke.wireguardautotunnel.service.tunnel.VpnService
|
||||
import com.zaneschepke.wireguardautotunnel.util.Constants
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.collectLatest
|
||||
import kotlinx.coroutines.launch
|
||||
import org.amnezia.awg.backend.Tunnel
|
||||
import timber.log.Timber
|
||||
import java.net.InetAddress
|
||||
import javax.inject.Inject
|
||||
@@ -56,7 +57,7 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
|
||||
|
||||
private val networkEventsFlow = MutableStateFlow(WatcherState())
|
||||
|
||||
private lateinit var watcherJob: Job
|
||||
private var watcherJob: Job? = null
|
||||
|
||||
private var wakeLock: PowerManager.WakeLock? = null
|
||||
private val tag = this.javaClass.name
|
||||
@@ -86,8 +87,8 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun stopService(extras: Bundle?) {
|
||||
super.stopService(extras)
|
||||
override fun stopService() {
|
||||
super.stopService()
|
||||
wakeLock?.let {
|
||||
if (it.isHeld) {
|
||||
it.release()
|
||||
@@ -134,8 +135,10 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
|
||||
}
|
||||
|
||||
private fun cancelWatcherJob() {
|
||||
if (this::watcherJob.isInitialized) {
|
||||
watcherJob.cancel()
|
||||
try {
|
||||
watcherJob?.cancel()
|
||||
} catch (e : CancellationException) {
|
||||
Timber.i("Watcher job cancelled")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -231,7 +234,7 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
|
||||
}
|
||||
if (results.contains(false)) {
|
||||
Timber.i("Restarting VPN for ping failure")
|
||||
serviceManager.stopVpnService(this)
|
||||
serviceManager.stopVpnServiceForeground(this)
|
||||
delay(Constants.VPN_RESTART_DELAY)
|
||||
serviceManager.startVpnServiceForeground(this)
|
||||
delay(Constants.PING_COOLDOWN)
|
||||
@@ -319,7 +322,9 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
|
||||
)
|
||||
val ssid = wifiService.getNetworkName(it.networkCapabilities)
|
||||
ssid?.let {
|
||||
Timber.i("Detected SSID: $ssid")
|
||||
if(it.contains(Constants.UNREADABLE_SSID)) {
|
||||
Timber.w("SSID unreadable: missing permissions")
|
||||
} else Timber.i("Detected valid SSID")
|
||||
appDataRepository.appState.setCurrentSsid(ssid)
|
||||
networkEventsFlow.value =
|
||||
networkEventsFlow.value.copy(
|
||||
@@ -376,7 +381,7 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
|
||||
|
||||
watcherState.isTunnelOffOnMobileDataConditionMet() -> {
|
||||
Timber.i("$autoTunnel - tunnel off on mobile data met, turning vpn off")
|
||||
serviceManager.stopVpnService(this)
|
||||
serviceManager.stopVpnServiceForeground(this)
|
||||
}
|
||||
|
||||
watcherState.isTunnelNotWifiNamePreferredMet(watcherState.currentNetworkSSID) -> {
|
||||
@@ -402,17 +407,17 @@ class WireGuardConnectivityWatcherService : ForegroundService() {
|
||||
|
||||
watcherState.isTrustedWifiConditionMet() -> {
|
||||
Timber.i("$autoTunnel - tunnel off on trusted wifi condition met, turning vpn off")
|
||||
serviceManager.stopVpnService(this)
|
||||
serviceManager.stopVpnServiceForeground(this)
|
||||
}
|
||||
|
||||
watcherState.isTunnelOffOnWifiConditionMet() -> {
|
||||
Timber.i("$autoTunnel - tunnel off on wifi condition met, turning vpn off")
|
||||
serviceManager.stopVpnService(this)
|
||||
serviceManager.stopVpnServiceForeground(this)
|
||||
}
|
||||
|
||||
watcherState.isTunnelOffOnNoConnectivityMet() -> {
|
||||
Timber.i("$autoTunnel - tunnel off on no connectivity met, turning vpn off")
|
||||
serviceManager.stopVpnService(this)
|
||||
serviceManager.stopVpnServiceForeground(this)
|
||||
}
|
||||
|
||||
else -> {
|
||||
|
||||
+10
-6
@@ -5,7 +5,6 @@ import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.core.app.ServiceCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.wireguard.android.backend.Tunnel
|
||||
import com.zaneschepke.wireguardautotunnel.R
|
||||
import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository
|
||||
import com.zaneschepke.wireguardautotunnel.receiver.NotificationActionReceiver
|
||||
@@ -16,10 +15,13 @@ import com.zaneschepke.wireguardautotunnel.util.Constants
|
||||
import com.zaneschepke.wireguardautotunnel.util.handshakeStatus
|
||||
import com.zaneschepke.wireguardautotunnel.util.mapPeerStats
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.amnezia.awg.backend.Tunnel
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@AndroidEntryPoint
|
||||
@@ -35,7 +37,7 @@ class WireGuardTunnelService : ForegroundService() {
|
||||
@Inject
|
||||
lateinit var notificationService: NotificationService
|
||||
|
||||
private lateinit var job: Job
|
||||
private var job: Job? = null
|
||||
|
||||
private var didShowConnected = false
|
||||
|
||||
@@ -117,8 +119,8 @@ class WireGuardTunnelService : ForegroundService() {
|
||||
)
|
||||
}
|
||||
|
||||
override fun stopService(extras: Bundle?) {
|
||||
super.stopService(extras)
|
||||
override fun stopService() {
|
||||
super.stopService()
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
vpnService.stopTunnel()
|
||||
didShowConnected = false
|
||||
@@ -177,8 +179,10 @@ class WireGuardTunnelService : ForegroundService() {
|
||||
}
|
||||
|
||||
private fun cancelJob() {
|
||||
if (this::job.isInitialized) {
|
||||
job.cancel()
|
||||
try {
|
||||
job?.cancel()
|
||||
} catch (e : CancellationException) {
|
||||
Timber.i("Tunnel job cancelled")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -40,7 +40,7 @@ class ShortcutsActivity : ComponentActivity() {
|
||||
this@ShortcutsActivity, tunnelConfig?.id, isManualStart = true,
|
||||
)
|
||||
|
||||
Action.STOP.name -> serviceManager.stopVpnService(
|
||||
Action.STOP.name -> serviceManager.stopVpnServiceForeground(
|
||||
this@ShortcutsActivity,
|
||||
isManualStop = true,
|
||||
)
|
||||
|
||||
+5
@@ -53,6 +53,11 @@ class AutoTunnelControlTile : TileService() {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onTileAdded() {
|
||||
super.onTileAdded()
|
||||
onStartListening()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
scope.cancel()
|
||||
|
||||
+10
-2
@@ -3,7 +3,6 @@ package com.zaneschepke.wireguardautotunnel.service.tile
|
||||
import android.os.Build
|
||||
import android.service.quicksettings.Tile
|
||||
import android.service.quicksettings.TileService
|
||||
import com.wireguard.android.backend.Tunnel
|
||||
import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig
|
||||
import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository
|
||||
import com.zaneschepke.wireguardautotunnel.service.foreground.ServiceManager
|
||||
@@ -13,6 +12,7 @@ import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.cancel
|
||||
import kotlinx.coroutines.launch
|
||||
import org.amnezia.awg.backend.Tunnel
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -69,13 +69,21 @@ class TunnelControlTile : TileService() {
|
||||
scope.cancel()
|
||||
}
|
||||
|
||||
override fun onTileAdded() {
|
||||
super.onTileAdded()
|
||||
onStartListening()
|
||||
}
|
||||
|
||||
override fun onClick() {
|
||||
super.onClick()
|
||||
unlockAndRun {
|
||||
scope.launch {
|
||||
try {
|
||||
if (vpnService.getState() == Tunnel.State.UP) {
|
||||
serviceManager.stopVpnService(this@TunnelControlTile, isManualStop = true)
|
||||
serviceManager.stopVpnServiceForeground(
|
||||
this@TunnelControlTile,
|
||||
isManualStop = true,
|
||||
)
|
||||
} else {
|
||||
serviceManager.startVpnServiceForeground(
|
||||
this@TunnelControlTile, manualStartConfig?.id, isManualStart = true,
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.zaneschepke.wireguardautotunnel.service.tunnel
|
||||
|
||||
import com.wireguard.android.backend.Tunnel
|
||||
import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import org.amnezia.awg.backend.Tunnel
|
||||
|
||||
interface VpnService : Tunnel {
|
||||
suspend fun startTunnel(tunnelConfig: TunnelConfig? = null): Tunnel.State
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.zaneschepke.wireguardautotunnel.service.tunnel
|
||||
|
||||
import com.wireguard.android.backend.Statistics
|
||||
import com.wireguard.android.backend.Tunnel
|
||||
import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig
|
||||
import org.amnezia.awg.backend.Statistics
|
||||
import org.amnezia.awg.backend.Tunnel
|
||||
|
||||
data class VpnState(
|
||||
val status: Tunnel.State = Tunnel.State.DOWN,
|
||||
|
||||
+20
-17
@@ -1,15 +1,12 @@
|
||||
package com.zaneschepke.wireguardautotunnel.service.tunnel
|
||||
|
||||
import com.wireguard.android.backend.Backend
|
||||
import com.wireguard.android.backend.BackendException
|
||||
import com.wireguard.android.backend.Statistics
|
||||
import com.wireguard.android.backend.Tunnel.State
|
||||
import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
|
||||
import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig
|
||||
import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository
|
||||
import com.zaneschepke.wireguardautotunnel.module.Kernel
|
||||
import com.zaneschepke.wireguardautotunnel.module.Userspace
|
||||
import com.zaneschepke.wireguardautotunnel.util.Constants
|
||||
import kotlinx.coroutines.CancellationException
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
@@ -18,6 +15,10 @@ import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import org.amnezia.awg.backend.Backend
|
||||
import org.amnezia.awg.backend.BackendException
|
||||
import org.amnezia.awg.backend.Statistics
|
||||
import org.amnezia.awg.backend.Tunnel
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -33,7 +34,7 @@ constructor(
|
||||
|
||||
private val scope = CoroutineScope(Dispatchers.IO)
|
||||
|
||||
private lateinit var statsJob: Job
|
||||
private var statsJob: Job? = null
|
||||
|
||||
private var backend: Backend = userspaceBackend
|
||||
|
||||
@@ -55,7 +56,7 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun startTunnel(tunnelConfig: TunnelConfig?): State {
|
||||
override suspend fun startTunnel(tunnelConfig: TunnelConfig?): Tunnel.State {
|
||||
return try {
|
||||
//TODO we need better error handling here
|
||||
val config = tunnelConfig ?: appDataRepository.getPrimaryOrFirstTunnel()
|
||||
@@ -65,18 +66,18 @@ constructor(
|
||||
val state =
|
||||
backend.setState(
|
||||
this,
|
||||
State.UP,
|
||||
Tunnel.State.UP,
|
||||
wgConfig,
|
||||
)
|
||||
state
|
||||
} else throw Exception("No tunnels")
|
||||
} catch (e: BackendException) {
|
||||
Timber.e("Failed to start tunnel with error: ${e.message}")
|
||||
State.DOWN
|
||||
Tunnel.State.DOWN
|
||||
}
|
||||
}
|
||||
|
||||
private fun emitTunnelState(state: State) {
|
||||
private fun emitTunnelState(state: Tunnel.State) {
|
||||
_vpnState.tryEmit(
|
||||
_vpnState.value.copy(
|
||||
status = state,
|
||||
@@ -102,8 +103,8 @@ constructor(
|
||||
|
||||
override suspend fun stopTunnel() {
|
||||
try {
|
||||
if (getState() == State.UP) {
|
||||
val state = backend.setState(this, State.DOWN, null)
|
||||
if (getState() == Tunnel.State.UP) {
|
||||
val state = backend.setState(this, Tunnel.State.DOWN, null)
|
||||
emitTunnelState(state)
|
||||
}
|
||||
} catch (e: BackendException) {
|
||||
@@ -111,7 +112,7 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getState(): State {
|
||||
override fun getState(): Tunnel.State {
|
||||
return backend.getState(this)
|
||||
}
|
||||
|
||||
@@ -119,11 +120,11 @@ constructor(
|
||||
return _vpnState.value.tunnelConfig?.name ?: ""
|
||||
}
|
||||
|
||||
override fun onStateChange(state: State) {
|
||||
override fun onStateChange(state: Tunnel.State) {
|
||||
val tunnel = this
|
||||
emitTunnelState(state)
|
||||
WireGuardAutoTunnel.requestTunnelTileServiceStateUpdate(WireGuardAutoTunnel.instance)
|
||||
if (state == State.UP) {
|
||||
if (state == Tunnel.State.UP) {
|
||||
statsJob =
|
||||
scope.launch {
|
||||
while (true) {
|
||||
@@ -133,9 +134,11 @@ constructor(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (state == State.DOWN) {
|
||||
if (this::statsJob.isInitialized) {
|
||||
statsJob.cancel()
|
||||
if (state == Tunnel.State.DOWN) {
|
||||
try {
|
||||
statsJob?.cancel()
|
||||
} catch (e : CancellationException) {
|
||||
Timber.i("Stats job cancelled")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,6 @@ import android.widget.Toast
|
||||
import androidx.compose.runtime.mutableStateListOf
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.wireguard.android.backend.GoBackend
|
||||
import com.zaneschepke.logcatter.Logcatter
|
||||
import com.zaneschepke.logcatter.model.LogMessage
|
||||
import com.zaneschepke.wireguardautotunnel.R
|
||||
@@ -20,6 +19,7 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import org.amnezia.awg.backend.GoBackend
|
||||
import timber.log.Timber
|
||||
import java.time.Instant
|
||||
import javax.inject.Inject
|
||||
@@ -118,12 +118,12 @@ constructor(
|
||||
fun readLogCatOutput() =
|
||||
viewModelScope.launch(viewModelScope.coroutineContext + Dispatchers.IO) {
|
||||
launch {
|
||||
Logcatter.logs {
|
||||
Logcatter.logs(callback = {
|
||||
logs.add(it)
|
||||
if (logs.size > Constants.LOG_BUFFER_SIZE) {
|
||||
logs.removeRange(0, (logs.size - Constants.LOG_BUFFER_SIZE).toInt())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,13 +4,17 @@ import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.rounded.Home
|
||||
import androidx.compose.material.icons.rounded.QuestionMark
|
||||
import androidx.compose.material.icons.rounded.Settings
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import com.zaneschepke.wireguardautotunnel.R
|
||||
import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
|
||||
import com.zaneschepke.wireguardautotunnel.ui.common.navigation.BottomNavItem
|
||||
import com.zaneschepke.wireguardautotunnel.util.StringValue
|
||||
|
||||
sealed class Screen(val route: String) {
|
||||
data object Main : Screen("main") {
|
||||
val navItem =
|
||||
BottomNavItem(
|
||||
name = "Tunnels",
|
||||
name = WireGuardAutoTunnel.instance.getString(R.string.tunnels),
|
||||
route = route,
|
||||
icon = Icons.Rounded.Home,
|
||||
)
|
||||
@@ -19,7 +23,7 @@ sealed class Screen(val route: String) {
|
||||
data object Settings : Screen("settings") {
|
||||
val navItem =
|
||||
BottomNavItem(
|
||||
name = "Settings",
|
||||
name = WireGuardAutoTunnel.instance.getString(R.string.settings),
|
||||
route = route,
|
||||
icon = Icons.Rounded.Settings,
|
||||
)
|
||||
@@ -28,7 +32,7 @@ sealed class Screen(val route: String) {
|
||||
data object Support : Screen("support") {
|
||||
val navItem =
|
||||
BottomNavItem(
|
||||
name = "Support",
|
||||
name = WireGuardAutoTunnel.instance.getString(R.string.support),
|
||||
route = route,
|
||||
icon = Icons.Rounded.QuestionMark,
|
||||
)
|
||||
|
||||
@@ -17,9 +17,9 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.wireguard.android.backend.Statistics
|
||||
import com.zaneschepke.wireguardautotunnel.util.NumberUtils
|
||||
import com.zaneschepke.wireguardautotunnel.util.toThreeDecimalPlaceString
|
||||
import org.amnezia.awg.backend.Statistics
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
|
||||
+6
-1
@@ -28,7 +28,12 @@ fun ConfigurationToggle(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
) {
|
||||
Text(label, textAlign = TextAlign.Start)
|
||||
Text(label, textAlign = TextAlign.Start, modifier = Modifier
|
||||
.weight(
|
||||
weight = 1.0f,
|
||||
fill = false,
|
||||
),
|
||||
softWrap = true)
|
||||
Switch(
|
||||
modifier = modifier,
|
||||
enabled = enabled,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.zaneschepke.wireguardautotunnel.ui.models
|
||||
|
||||
import com.wireguard.config.Interface
|
||||
import org.amnezia.awg.config.Interface
|
||||
|
||||
data class InterfaceProxy(
|
||||
var privateKey: String = "",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.zaneschepke.wireguardautotunnel.ui.models
|
||||
|
||||
import com.wireguard.config.Peer
|
||||
import org.amnezia.awg.config.Peer
|
||||
|
||||
data class PeerProxy(
|
||||
var publicKey: String = "",
|
||||
|
||||
+7
-7
@@ -7,11 +7,6 @@ import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.wireguard.config.Config
|
||||
import com.wireguard.config.Interface
|
||||
import com.wireguard.config.Peer
|
||||
import com.wireguard.crypto.Key
|
||||
import com.wireguard.crypto.KeyPair
|
||||
import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
|
||||
import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig
|
||||
import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository
|
||||
@@ -28,6 +23,11 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import org.amnezia.awg.config.Config
|
||||
import org.amnezia.awg.config.Interface
|
||||
import org.amnezia.awg.config.Peer
|
||||
import org.amnezia.awg.crypto.Key
|
||||
import org.amnezia.awg.crypto.KeyPair
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -198,12 +198,12 @@ constructor(
|
||||
val tunnelConfig = when (uiState.value.tunnel) {
|
||||
null -> TunnelConfig(
|
||||
name = _uiState.value.tunnelName,
|
||||
wgQuick = config.toWgQuickString(),
|
||||
wgQuick = config.toAwgQuickString(),
|
||||
)
|
||||
|
||||
else -> uiState.value.tunnel!!.copy(
|
||||
name = _uiState.value.tunnelName,
|
||||
wgQuick = config.toWgQuickString(),
|
||||
wgQuick = config.toAwgQuickString(),
|
||||
)
|
||||
}
|
||||
updateTunnelConfig(tunnelConfig)
|
||||
|
||||
+26
-3
@@ -71,8 +71,12 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.focus.onFocusChanged
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollSource
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
@@ -85,7 +89,6 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import androidx.navigation.NavController
|
||||
import com.journeyapps.barcodescanner.ScanContract
|
||||
import com.journeyapps.barcodescanner.ScanOptions
|
||||
import com.wireguard.android.backend.Tunnel
|
||||
import com.zaneschepke.wireguardautotunnel.R
|
||||
import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
|
||||
import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig
|
||||
@@ -106,6 +109,7 @@ import com.zaneschepke.wireguardautotunnel.util.truncateWithEllipsis
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import org.amnezia.awg.backend.Tunnel
|
||||
|
||||
@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter")
|
||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
|
||||
@@ -124,6 +128,25 @@ fun MainScreen(
|
||||
val sheetState = rememberModalBottomSheetState()
|
||||
var showBottomSheet by remember { mutableStateOf(false) }
|
||||
|
||||
// Nested scroll for control FAB
|
||||
val nestedScrollConnection = remember {
|
||||
object : NestedScrollConnection {
|
||||
override fun onPreScroll(available: Offset, source: NestedScrollSource): Offset {
|
||||
// Hide FAB
|
||||
if (available.y < -1) {
|
||||
isVisible.value = false
|
||||
}
|
||||
// Show FAB
|
||||
if (available.y > 1) {
|
||||
isVisible.value = true
|
||||
}
|
||||
|
||||
return Offset.Zero
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var showDeleteTunnelAlertDialog by remember { mutableStateOf(false) }
|
||||
var selectedTunnel by remember { mutableStateOf<TunnelConfig?>(null) }
|
||||
val uiState by viewModel.uiState.collectAsStateWithLifecycle()
|
||||
@@ -377,8 +400,8 @@ fun MainScreen(
|
||||
verticalArrangement = Arrangement.Top,
|
||||
modifier =
|
||||
Modifier
|
||||
.fillMaxWidth()
|
||||
.overscroll(ScrollableDefaults.overscrollEffect()),
|
||||
.fillMaxSize()
|
||||
.overscroll(ScrollableDefaults.overscrollEffect()).nestedScroll(nestedScrollConnection),
|
||||
state = rememberLazyListState(0, uiState.tunnels.count()),
|
||||
userScrollEnabled = true,
|
||||
reverseLayout = false,
|
||||
|
||||
+3
-3
@@ -7,7 +7,6 @@ import android.net.Uri
|
||||
import android.provider.OpenableColumns
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.wireguard.config.Config
|
||||
import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
|
||||
import com.zaneschepke.wireguardautotunnel.data.model.Settings
|
||||
import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig
|
||||
@@ -25,6 +24,7 @@ import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.amnezia.awg.config.Config
|
||||
import timber.log.Timber
|
||||
import java.io.InputStream
|
||||
import java.util.zip.ZipInputStream
|
||||
@@ -119,7 +119,7 @@ constructor(
|
||||
val bufferReader = stream.bufferedReader(charset = Charsets.UTF_8)
|
||||
val config = Config.parse(bufferReader)
|
||||
val tunnelName = getNameFromFileName(fileName)
|
||||
addTunnel(TunnelConfig(name = tunnelName, wgQuick = config.toWgQuickString()))
|
||||
addTunnel(TunnelConfig(name = tunnelName, wgQuick = config.toAwgQuickString()))
|
||||
withContext(Dispatchers.IO) { stream.close() }
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ constructor(
|
||||
val name = getNameFromFileName(it.name)
|
||||
val config = Config.parse(zip)
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
addTunnel(TunnelConfig(name = name, wgQuick = config.toWgQuickString()))
|
||||
addTunnel(TunnelConfig(name = name, wgQuick = config.toAwgQuickString()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-3
@@ -26,6 +26,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
@@ -70,8 +71,6 @@ import androidx.navigation.NavController
|
||||
import com.google.accompanist.permissions.ExperimentalPermissionsApi
|
||||
import com.google.accompanist.permissions.isGranted
|
||||
import com.google.accompanist.permissions.rememberPermissionState
|
||||
import com.wireguard.android.backend.Tunnel
|
||||
import com.wireguard.android.backend.WgQuickBackend
|
||||
import com.zaneschepke.wireguardautotunnel.R
|
||||
import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
|
||||
import com.zaneschepke.wireguardautotunnel.ui.AppViewModel
|
||||
@@ -85,6 +84,8 @@ import com.zaneschepke.wireguardautotunnel.util.FileUtils
|
||||
import com.zaneschepke.wireguardautotunnel.util.Result
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import org.amnezia.awg.backend.AwgQuickBackend
|
||||
import org.amnezia.awg.backend.Tunnel
|
||||
import timber.log.Timber
|
||||
import xyz.teamgravity.pin_lock_compose.PinManager
|
||||
import java.io.File
|
||||
@@ -550,7 +551,7 @@ fun SettingsScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (WgQuickBackend.hasKernelSupport()) {
|
||||
if (AwgQuickBackend.hasKernelSupport()) {
|
||||
Surface(
|
||||
tonalElevation = 2.dp,
|
||||
shadowElevation = 2.dp,
|
||||
|
||||
+1
-1
@@ -6,7 +6,6 @@ import android.location.LocationManager
|
||||
import androidx.core.location.LocationManagerCompat
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.wireguard.android.util.RootShell
|
||||
import com.zaneschepke.wireguardautotunnel.WireGuardAutoTunnel
|
||||
import com.zaneschepke.wireguardautotunnel.data.model.Settings
|
||||
import com.zaneschepke.wireguardautotunnel.data.repository.AppDataRepository
|
||||
@@ -20,6 +19,7 @@ import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import org.amnezia.awg.util.RootShell
|
||||
import timber.log.Timber
|
||||
import javax.inject.Inject
|
||||
|
||||
|
||||
+23
-3
@@ -37,6 +37,7 @@ import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
@@ -122,7 +123,13 @@ fun SupportScreen(
|
||||
Text(
|
||||
stringResource(id = R.string.docs_description),
|
||||
textAlign = TextAlign.Justify,
|
||||
modifier = Modifier.padding(start = 10.dp),
|
||||
modifier = Modifier
|
||||
.padding(start = 10.dp)
|
||||
.weight(
|
||||
weight = 1.0f,
|
||||
fill = false,
|
||||
),
|
||||
softWrap = true
|
||||
)
|
||||
}
|
||||
Icon(
|
||||
@@ -270,8 +277,21 @@ fun SupportScreen(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.padding(25.dp),
|
||||
) {
|
||||
Text("Version: ${BuildConfig.VERSION_NAME}", modifier = Modifier.focusable())
|
||||
Text("Mode: ${if (uiState.settings.isKernelEnabled) "Kernel" else "Userspace"}")
|
||||
val version = buildAnnotatedString {
|
||||
append(stringResource(id = R.string.version))
|
||||
append(": ")
|
||||
append(BuildConfig.VERSION_NAME)
|
||||
}
|
||||
val mode = buildAnnotatedString {
|
||||
append(stringResource(R.string.mode))
|
||||
append(": ")
|
||||
when(uiState.settings.isKernelEnabled){
|
||||
true -> append(stringResource(id = R.string.kernel))
|
||||
false -> append(stringResource(id = R.string.userspace))
|
||||
}
|
||||
}
|
||||
Text(version.text, modifier = Modifier.focusable())
|
||||
Text(mode.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,4 +35,6 @@ object Constants {
|
||||
|
||||
const val TUNNEL_EXTRA_KEY = "tunnelId"
|
||||
|
||||
const val UNREADABLE_SSID = "<unknown ssid>"
|
||||
|
||||
}
|
||||
|
||||
@@ -2,15 +2,14 @@ package com.zaneschepke.wireguardautotunnel.util
|
||||
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.pm.PackageInfo
|
||||
import com.wireguard.android.backend.Statistics
|
||||
import com.wireguard.android.backend.Statistics.PeerStats
|
||||
import com.wireguard.crypto.Key
|
||||
import com.zaneschepke.wireguardautotunnel.data.model.TunnelConfig
|
||||
import com.zaneschepke.wireguardautotunnel.service.tunnel.HandshakeStatus
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.amnezia.awg.backend.Statistics
|
||||
import org.amnezia.awg.crypto.Key
|
||||
import java.math.BigDecimal
|
||||
import java.text.DecimalFormat
|
||||
import kotlin.coroutines.CoroutineContext
|
||||
@@ -50,15 +49,15 @@ typealias TunnelConfigs = List<TunnelConfig>
|
||||
|
||||
typealias Packages = List<PackageInfo>
|
||||
|
||||
fun Statistics.mapPeerStats(): Map<Key, PeerStats?> {
|
||||
fun Statistics.mapPeerStats(): Map<Key, Statistics.PeerStats?> {
|
||||
return this.peers().associateWith { key -> (this.peer(key)) }
|
||||
}
|
||||
|
||||
fun PeerStats.latestHandshakeSeconds(): Long? {
|
||||
fun Statistics.PeerStats.latestHandshakeSeconds(): Long? {
|
||||
return NumberUtils.getSecondsBetweenTimestampAndNow(this.latestHandshakeEpochMillis)
|
||||
}
|
||||
|
||||
fun PeerStats.handshakeStatus(): HandshakeStatus {
|
||||
fun Statistics.PeerStats.handshakeStatus(): HandshakeStatus {
|
||||
// TODO add never connected status after duration
|
||||
return this.latestHandshakeSeconds().let {
|
||||
when {
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_channel_background" />
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1 @@
|
||||
unqualifiedResLocale=en-US
|
||||
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">WG Tunnel</string>
|
||||
<string name="error_file_extension">Dies ist keine .conf oder .zip Datei</string>
|
||||
<string name="no_tunnels">Noch keine Tunnel hinzugefügt!</string>
|
||||
<string name="watcher_notification_text_active">Überwachung der Netzwerkänderungen: aktiv</string>
|
||||
<string name="tunnels">Tunnel</string>
|
||||
<string name="enable_auto_tunnel">Starte automatisches Verbinden</string>
|
||||
<string name="tunnel_mobile_data">Verbinden im Mobilnetzwerk</string>
|
||||
<string name="one_tunnel_required">Mindestens eine Verbindung wird für diese Funktion benötigt</string>
|
||||
<string name="privacy_policy">Siehe Privacy Policy</string>
|
||||
<string name="disable_auto_tunnel">Stoppe automatisches Verbinden</string>
|
||||
<string name="okay">Okay</string>
|
||||
<string name="tunnel_on_ethernet">Verbindung über Ethernet</string>
|
||||
<string name="search_icon">Suchsymbol</string>
|
||||
<string name="attempt_connection">Versuche zu verbinden..</string>
|
||||
<string name="auto_tunneling">Automatisches verbinden</string>
|
||||
<string name="default_vpn_off">Primärer VPN aus</string>
|
||||
<string name="turn_on_tunnel">Für diese Altion muss eine Verbindung bestehen</string>
|
||||
<string name="watcher_notification_text_paused">Überwachung der Netzwerkänderungen: pausiert</string>
|
||||
<string name="tunnel_start_title">VPN verbunden</string>
|
||||
<string name="tunnel_start_text">Mit Tunnel verbunden</string>
|
||||
<string name="notification_permission_required">Berechtigung für die Benachrichtigung benötigt.</string>
|
||||
<string name="add_trusted_ssid">Vertrauenswürdiger WiFi-Name hinzugügen</string>
|
||||
<string name="prominent_background_location_message">Diese Funktion benötigt Standortberechtigung im Hintergrund um die WiFi SSIDs auch wenn die Applikation geschlossen ist zu überwachen. Für mehr Infos, siehe Privacy Policy auf der Hilfeseite.</string>
|
||||
<string name="prominent_background_location_title">Vereinbarung der Standortberechtigung im Hintergrund</string>
|
||||
<string name="thank_you">Danke fürs benutzen von WG Tunnel!</string>
|
||||
<string name="trusted_ssid_empty_description">SSID eingeben</string>
|
||||
<string name="trusted_ssid_value_description">SSID bestätigen</string>
|
||||
<string name="add_tunnels_text">Von Datei oder ZIP hinzufügen</string>
|
||||
<string name="open_file">Datei geöffnet</string>
|
||||
<string name="add_from_qr">Von QR-Code hinzufügen</string>
|
||||
<string name="qr_scan">Scanne QR</string>
|
||||
<string name="tunnel_name">Verbindungsname</string>
|
||||
<string name="add_tunnel">Verbindung hinzufügen</string>
|
||||
<string name="exclude">Ausgenommen</string>
|
||||
<string name="include">Eingeschlossen</string>
|
||||
<string name="tunnel_all">Verbinde alle Apps</string>
|
||||
<string name="config_changes_saved">Änderungen der Konfiguration gespeichert.</string>
|
||||
<string name="save_changes">Speichern</string>
|
||||
<string name="icon">Symbol</string>
|
||||
<string name="no_thanks">Nein danke</string>
|
||||
<string name="turn_on">Einschalten</string>
|
||||
<string name="map">Karte</string>
|
||||
<string name="public_key">Öffentlicher Schlüssel</string>
|
||||
<string name="addresses">Adressen</string>
|
||||
<string name="dns_servers">DNS-Server</string>
|
||||
<string name="mtu">MTU</string>
|
||||
<string name="peer">Peer</string>
|
||||
<string name="allowed_ips">Erlaubte IPs</string>
|
||||
<string name="endpoint">Endpunkt</string>
|
||||
<string name="name">Name</string>
|
||||
<string name="restart">Verbindung neustarten</string>
|
||||
<string name="vpn_connection_failed">Verbindung fehlgeschlagen</string>
|
||||
<string name="always_on_vpn_support">Erlaube Always-On VPN</string>
|
||||
<string name="location_services_not_detected">Standortdienste Nicht Erkannt</string>
|
||||
<string name="hint_search_packages">Suche packete</string>
|
||||
<string name="clear_icon">Lösche Symbol</string>
|
||||
<string name="vpn_starting">VPN startet</string>
|
||||
<string name="db_name">wg-tunnel-db</string>
|
||||
<string name="scanning_qr">Scanne nach QR</string>
|
||||
<string name="none">Keine vertrauenswürdigen WiFi Namen</string>
|
||||
<string name="other">Andere</string>
|
||||
<string name="vpn_on">VPN an</string>
|
||||
<string name="vpn_off">VPN aus</string>
|
||||
<string name="default_vpn_on">Primärer VPN an</string>
|
||||
<string name="create_import">Starte von Grund auf neu</string>
|
||||
<string name="turn_off_auto">Für diese Aktion muss automatisches Verbinden ausgeschaltet oder pausiert sein</string>
|
||||
<string name="add_peer">Peer hinzufügen</string>
|
||||
<string name="done">Erledigt</string>
|
||||
<string name="rotate_keys">Schlüssel ändern</string>
|
||||
<string name="private_key">Privater Schlüssel</string>
|
||||
<string name="copy_public_key">Öffentlicher Schlüssel kopieren</string>
|
||||
<string name="base64_key">base64-Schlüssel</string>
|
||||
<string name="comma_separated_list">Kommaseparierte Liste</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,162 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="map">Mapa</string>
|
||||
<string name="allowed_ips">Allowed IPs</string>
|
||||
<string name="email_chooser">Enviar un email…</string>
|
||||
<string name="go">ir</string>
|
||||
<string name="discord_description">Únete a la comunidad</string>
|
||||
<string name="kernel">Kernel</string>
|
||||
<string name="restart">Reiniciar túnel</string>
|
||||
<string name="vpn_connection_failed">Error de conexión</string>
|
||||
<string name="error_none">Sin error</string>
|
||||
<string name="other">Otros</string>
|
||||
<string name="add_peer">Añadir peer</string>
|
||||
<string name="done">Hecho</string>
|
||||
<string name="copy_public_key">Copiar public key</string>
|
||||
<string name="base64_key">clave base64</string>
|
||||
<string name="exported_configs_message">Configuración exportada a Descargas</string>
|
||||
<string name="tunnel_on_wifi">Túnel en Wi-Fi no de confianza</string>
|
||||
<string name="location_services_missing_message">La app no detecta activado el servicio de ubicación en tu dispositivo. Dependiendo del dispositivo, esto podría hacer que la característica de Wi-Fi no de confianza falle al leer el nombre Wi-Fi. ¿Quieres continuar de todas formas?</string>
|
||||
<string name="excluded">excluida(s)</string>
|
||||
<string name="all">todas</string>
|
||||
<string name="mobile_data_tunnel">Establecer como túnel en datos móviles</string>
|
||||
<string name="use_tunnel_on_wifi_name">Usar tunnel en nombre Wi-Fi</string>
|
||||
<string name="disabled">desactivado</string>
|
||||
<string name="version">Versión</string>
|
||||
<string name="userspace">Espacio del usuario</string>
|
||||
<string name="mode">Modo</string>
|
||||
<string name="support">Ayuda</string>
|
||||
<string name="private_key">Clave privada</string>
|
||||
<string name="trusted_ssid_value_description">Enviar SSID</string>
|
||||
<string name="trusted_ssid_empty_description">Introducir SSID</string>
|
||||
<string name="add_tunnels_text">Añadir desde archivo o zip</string>
|
||||
<string name="open_file">Abrir archivo</string>
|
||||
<string name="add_from_qr">Añadir mediante código QR</string>
|
||||
<string name="qr_scan">Escanear QR</string>
|
||||
<string name="tunnel_name">Nombre de túnel</string>
|
||||
<string name="add_tunnel">Añadir túnel</string>
|
||||
<string name="exclude">Excluir</string>
|
||||
<string name="include">Incluir</string>
|
||||
<string name="tunnel_all">Todas las apps por el túnel</string>
|
||||
<string name="config_changes_saved">Cambios de configuración guardados.</string>
|
||||
<string name="save_changes">Guardar</string>
|
||||
<string name="icon">Icono</string>
|
||||
<string name="no_thanks">No gracias</string>
|
||||
<string name="turn_on">Activar</string>
|
||||
<string name="mtu">MTU</string>
|
||||
<string name="dns_servers">DNS servers</string>
|
||||
<string name="addresses">Addresses</string>
|
||||
<string name="public_key">Public key</string>
|
||||
<string name="error_file_extension">No es un archivo .conf o .zip</string>
|
||||
<string name="turn_off_tunnel">Desactiva antes el túnel</string>
|
||||
<string name="no_tunnels">¡Ningún túnel añadido aún!</string>
|
||||
<string name="watcher_notification_text_paused">Monitoreando cambios de red: En pausa</string>
|
||||
<string name="watcher_notification_text_active">Monitoreando cambios de red: Activado</string>
|
||||
<string name="tunnel_start_title">VPN conectada</string>
|
||||
<string name="tunnel_start_text">Conectado al túnel</string>
|
||||
<string name="notification_permission_required">Necesita permiso de notificaciones.</string>
|
||||
<string name="add_trusted_ssid">Añadir nombres Wi-Fi de confianza</string>
|
||||
<string name="tunnels">Túneles</string>
|
||||
<string name="enable_auto_tunnel">Iniciar túnel-automático</string>
|
||||
<string name="disable_auto_tunnel">Parar túnel-automático</string>
|
||||
<string name="tunnel_mobile_data">Activar túnel en datos móviles</string>
|
||||
<string name="one_tunnel_required">Esta característica necesita ser usada en almenos por un túnel</string>
|
||||
<string name="privacy_policy">Ver Política de Privacidad</string>
|
||||
<string name="okay">OK</string>
|
||||
<string name="tunnel_on_ethernet">Túnel en ethernet</string>
|
||||
<string name="prominent_background_location_title">Divulgación de la ubicación en segundo plano</string>
|
||||
<string name="thank_you">¡Gracias por usar WG Tunnel!</string>
|
||||
<string name="endpoint">Endpoint</string>
|
||||
<string name="peer">Peer</string>
|
||||
<string name="name">Nombre</string>
|
||||
<string name="always_on_vpn_support">Permitir VPN siempre-activada</string>
|
||||
<string name="location_services_not_detected">Servicios de Ubicación No Detectados</string>
|
||||
<string name="hint_search_packages">Buscar paquetes</string>
|
||||
<string name="clear_icon">Icono claro</string>
|
||||
<string name="attempt_connection">Intentando conexión...</string>
|
||||
<string name="vpn_starting">Iniciando VPN</string>
|
||||
<string name="db_name">wg-tunnel-db</string>
|
||||
<string name="scanning_qr">Escaneando QR</string>
|
||||
<string name="none">Sin nombres Wi-Fi de confianza</string>
|
||||
<string name="auto_tunneling">Túnel-automático</string>
|
||||
<string name="vpn_on">VPN on</string>
|
||||
<string name="vpn_off">VPN off</string>
|
||||
<string name="default_vpn_on">VPN Principal on</string>
|
||||
<string name="default_vpn_off">VPN Principal off</string>
|
||||
<string name="create_import">Crear desde cero</string>
|
||||
<string name="turn_off_auto">La acción necesita que túnel-automático esté desactivado o en pausa</string>
|
||||
<string name="turn_on_tunnel">La acción necesita un túnel activado</string>
|
||||
<string name="rotate_keys">Rotar claves</string>
|
||||
<string name="comma_separated_list">lista separada por comas</string>
|
||||
<string name="random">(aleatorio)</string>
|
||||
<string name="optional">(opcional)</string>
|
||||
<string name="optional_no_recommend">(opcional, no recomendado)</string>
|
||||
<string name="seconds">segundos</string>
|
||||
<string name="cancel">Cancelar</string>
|
||||
<string name="error_authentication_failed">Fallo de autenticación</string>
|
||||
<string name="error_authorization_failed">Fallo de autorización</string>
|
||||
<string name="enabled_app_shortcuts">Habilitar acesos directos de app</string>
|
||||
<string name="export_configs">Exportar configuración</string>
|
||||
<string name="background_location_required">Se necesita ubicación en segundo plano</string>
|
||||
<string name="location_services_required">Se necesita servicio de ubicación</string>
|
||||
<string name="precise_location_required">Necesita ubicación precisa</string>
|
||||
<string name="unknown_error">Error desconocido</string>
|
||||
<string name="email_subject">Ayuda WG Tunnel</string>
|
||||
<string name="interface_">Interfaz</string>
|
||||
<string name="listen_port">Puerto de escucha</string>
|
||||
<string name="preshared_key">Clave previamente compartida</string>
|
||||
<string name="persistent_keepalive">Keepalive persistente</string>
|
||||
<string name="search_icon">Icono de búsqueda</string>
|
||||
<string name="docs_description">Leer documentación</string>
|
||||
<string name="email_description">Envíame un email</string>
|
||||
<string name="support_help_text">Si tienes problemas, ideas para mejoras, o simlemente comprometerte, tienes disponibles los siguientes recursos:</string>
|
||||
<string name="use_kernel">Usar módulo del Kernel</string>
|
||||
<string name="error_ssid_exists">SSID existente</string>
|
||||
<string name="error_root_denied">Shell root denegado</string>
|
||||
<string name="error_no_file_explorer">Explorador de archivos no instalado</string>
|
||||
<string name="error_invalid_code">Código QR no valido</string>
|
||||
<string name="auto_tunnel_title">Servicio túnel-automático</string>
|
||||
<string name="delete_tunnel">Eliminar túnel</string>
|
||||
<string name="delete_tunnel_message">¿Estás seguro de que quieres eliminar este túnel?</string>
|
||||
<string name="yes">Sí</string>
|
||||
<string name="resume">Reanudar</string>
|
||||
<string name="pause">Pausar</string>
|
||||
<string name="active">activado</string>
|
||||
<string name="paused">en pausa</string>
|
||||
<string name="tunneling_apps">Apps por el túnel</string>
|
||||
<string name="included">incluida(s)</string>
|
||||
<string name="always_on_disabled">VPN siempre-activada ha intentado iniciar un túnel, pero está característica está deshabilitada en los ajustes.</string>
|
||||
<string name="no_email_detected">Ninguna app de email detectada</string>
|
||||
<string name="no_browser_detected">Ningún navegador detectado</string>
|
||||
<string name="logs_saved">Registros guardados en Descargas</string>
|
||||
<string name="open_issue">Abrir una incidencia</string>
|
||||
<string name="read_logs">Leer los registros</string>
|
||||
<string name="auto">(automático)</string>
|
||||
<string name="config_parse_error">Fallo al analizar la configuración</string>
|
||||
<string name="incorrect_pin">El pin no es correcto</string>
|
||||
<string name="pin_created">Pin creado con éxito</string>
|
||||
<string name="enter_pin">Introduce tu pin</string>
|
||||
<string name="create_pin">Crear pin</string>
|
||||
<string name="enable_app_lock">Bloqueo de app activado</string>
|
||||
<string name="restart_on_ping">Reiniciar al fallar ping (beta)</string>
|
||||
<string name="set_primary_tunnel">Establecer como túnel Principal</string>
|
||||
<string name="no_wifi_names_configured">No hay nombres Wi-Fi configurados para este túnel</string>
|
||||
<string name="general">General</string>
|
||||
<string name="edit_tunnel">Editar túnel</string>
|
||||
<string name="auto_on">Reanudar túnel-automático</string>
|
||||
<string name="auto_off">Pausar túnel-automático</string>
|
||||
<string name="auto_tun_on">Reanudar el túnel automático</string>
|
||||
<string name="auto_tun_off">Pausa del túnel automático</string>
|
||||
<string name="settings">Ajustes</string>
|
||||
<string name="app_name">WG Tunnel</string>
|
||||
<string name="vpn_channel_id">Canal VPN</string>
|
||||
<string name="vpn_channel_name">Canal de notificación VPN</string>
|
||||
<string name="watcher_channel_id">Canal del obvervador</string>
|
||||
<string name="watcher_channel_name">Canal de notificación del obvervador</string>
|
||||
<string name="prominent_background_location_message">La monitorización SSID Wi-Fi necesita de permiso de ubicación en segundo plano incluso si la app está cerrada. Mira el enlace a la Política de Privacidad en la pantalla de ayuda para más detalles.</string>
|
||||
<string name="privacy_policy_url" translatable="false"></string>
|
||||
<string name="docs_url" translatable="false"></string>
|
||||
<string name="github_url" translatable="false"></string>
|
||||
<string name="discord_url" translatable="false"></string>
|
||||
<string name="my_email" translatable="false"></string>
|
||||
</resources>
|
||||
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
</resources>
|
||||
@@ -0,0 +1,162 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">WG Tunnel</string>
|
||||
<string name="vpn_channel_id">VPN Kanalı</string>
|
||||
<string name="vpn_channel_name">VPN Bildirim Kanalı</string>
|
||||
<string name="watcher_channel_id">İzleyici Kanalı</string>
|
||||
<string name="watcher_channel_name">İzleyici Bildirim Kanalı</string>
|
||||
<string name="github_url" translatable="false">https://github.com/zaneschepke/wgtunnel/issues</string>
|
||||
<string name="docs_url" translatable="false">https://zaneschepke.com/wgtunnel-docs/overview.html</string>
|
||||
<string name="privacy_policy_url" translatable="false">https://zaneschepke.com/wgtunnel-docs/privacypolicy.html</string>
|
||||
<string name="error_file_extension">Dosya bir .conf veya .zip değil</string>
|
||||
<string name="turn_off_tunnel">Eylem tünelin kapalı olmasını gerektiriyor</string>
|
||||
<string name="no_tunnels">Henüz bir tünel ekli değil!</string>
|
||||
<string name="discord_url" translatable="false">https://discord.gg/rbRRNh6H7V</string>
|
||||
<string name="watcher_notification_text_active">Ağ durumu değişikliklerini izleme: etkin</string>
|
||||
<string name="watcher_notification_text_paused">Ağ durumu değişikliklerini izleme: duraklatıldı</string>
|
||||
<string name="tunnel_start_title">VPN bağlandı</string>
|
||||
<string name="tunnel_start_text">Tünele bağlı</string>
|
||||
<string name="notification_permission_required">Bildirim izni gerekli.</string>
|
||||
<string name="add_trusted_ssid">Güvenilir Wi-Fi adı ekle</string>
|
||||
<string name="tunnels">Tüneller</string>
|
||||
<string name="enable_auto_tunnel">Otomatik tünellemeyi başlat</string>
|
||||
<string name="disable_auto_tunnel">Otomatik tünellemeyi durdur</string>
|
||||
<string name="tunnel_mobile_data">Mobil veri üzerinde tünel</string>
|
||||
<string name="one_tunnel_required">Bu özelliği kullanabilmek için en az bir tünel gereklidir.</string>
|
||||
<string name="privacy_policy">Gizlilik Politikası</string>
|
||||
<string name="okay">Tamam</string>
|
||||
<string name="tunnel_on_ethernet">Ethernet üzerinde tünel</string>
|
||||
<string name="prominent_background_location_message">Bu özellik, uygulama kapalıyken bile Wi-Fi SSID izlemesini etkinleştirmek için arka plan konumu izni gerektirir. Daha fazla bilgi için lütfen Destek ekranında bağlantısı verilen Gizlilik Politikasına bakın.</string>
|
||||
<string name="prominent_background_location_title">Arka Plan Konum Açıklaması</string>
|
||||
<string name="thank_you">WG Tunnel\'i kullandığınız için teşekkür ederiz!</string>
|
||||
<string name="trusted_ssid_empty_description">SSID\'yi gir</string>
|
||||
<string name="trusted_ssid_value_description">SSID\'yi gönder</string>
|
||||
<string name="add_tunnels_text">Dosyadan veya ZIP\'ten ekle</string>
|
||||
<string name="open_file">Dosya Aç</string>
|
||||
<string name="add_from_qr">QR kodundan ekle</string>
|
||||
<string name="qr_scan">QR kodu tarat</string>
|
||||
<string name="tunnel_name">Tünel adı</string>
|
||||
<string name="add_tunnel">Tünel ekle</string>
|
||||
<string name="exclude">Hariç tut</string>
|
||||
<string name="include">Dahil et</string>
|
||||
<string name="tunnel_all">Tüm uygulamaları dahil et</string>
|
||||
<string name="config_changes_saved">Yapılandırma değişiklikleri kaydedildi.</string>
|
||||
<string name="save_changes">Kaydet</string>
|
||||
<string name="icon">Simge</string>
|
||||
<string name="no_thanks">Hayır, teşekkürler</string>
|
||||
<string name="turn_on">Aç</string>
|
||||
<string name="map">Harita</string>
|
||||
<string name="public_key">Genel anahtar</string>
|
||||
<string name="addresses">Adresler</string>
|
||||
<string name="dns_servers">DNS sunucuları</string>
|
||||
<string name="mtu">MTU</string>
|
||||
<string name="peer">Eş (peer)</string>
|
||||
<string name="allowed_ips">İzin verilen IP\'ler</string>
|
||||
<string name="endpoint">Uç nokta (endpoint)</string>
|
||||
<string name="name">Ad</string>
|
||||
<string name="restart">Tüneli Yeniden Başlat</string>
|
||||
<string name="vpn_connection_failed">Bağlantı kurulamadı</string>
|
||||
<string name="always_on_vpn_support">Her Zaman Açık VPN\'e İzin Ver</string>
|
||||
<string name="location_services_not_detected">Konum Hizmetleri Algılanmadı</string>
|
||||
<string name="hint_search_packages">Uygulama arayın</string>
|
||||
<string name="clear_icon">Simgeyi Temizle</string>
|
||||
<string name="search_icon">Simge Ara</string>
|
||||
<string name="attempt_connection">Bağlantı kurulmaya çalışılıyor..</string>
|
||||
<string name="vpn_starting">VPN başlatılıyor</string>
|
||||
<string name="db_name">wg-tunnel-db</string>
|
||||
<string name="scanning_qr">QR taranıyor</string>
|
||||
<string name="none">Güvenilir Wi-Fi adı yok</string>
|
||||
<string name="other">Diğer</string>
|
||||
<string name="auto_tunneling">Otomatik tünelleme</string>
|
||||
<string name="vpn_on">VPN açık</string>
|
||||
<string name="vpn_off">VPN kapalı</string>
|
||||
<string name="default_vpn_on">Birincil VPN açık</string>
|
||||
<string name="default_vpn_off">Birincil VPN kapalı</string>
|
||||
<string name="create_import">Sıfırdan oluştur</string>
|
||||
<string name="turn_off_auto">Eylem, otomatik tünelin devre dışı bırakılmasını veya duraklatılmasını gerektirir</string>
|
||||
<string name="turn_on_tunnel">Eylem aktif tünel gerektirir</string>
|
||||
<string name="add_peer">Eş (peer) ekle</string>
|
||||
<string name="done">Tamam</string>
|
||||
<string name="interface_">Arayüz</string>
|
||||
<string name="rotate_keys">Tuşları döndür</string>
|
||||
<string name="private_key">Özel anahtar</string>
|
||||
<string name="copy_public_key">Genel anahtarı kopyala</string>
|
||||
<string name="base64_key">Base64 anahtarı</string>
|
||||
<string name="comma_separated_list">Virgül ile ayrılmış liste ekleyin</string>
|
||||
<string name="listen_port">Bağlantı noktası</string>
|
||||
<string name="random">(Rastgele)</string>
|
||||
<string name="optional">(İsteğe bağlı)</string>
|
||||
<string name="optional_no_recommend">(İsteğe bağlı, önerilmez)</string>
|
||||
<string name="preshared_key">Ön paylaşımlı anahtar</string>
|
||||
<string name="seconds">saniye</string>
|
||||
<string name="persistent_keepalive">Kalıcı olarak canlı tutma</string>
|
||||
<string name="cancel">İptal</string>
|
||||
<string name="error_authentication_failed">Kimlik doğrulama başarısız oldu</string>
|
||||
<string name="error_authorization_failed">Yetkilendirilemedi</string>
|
||||
<string name="enabled_app_shortcuts">Uygulama kısayollarını etkinleştir</string>
|
||||
<string name="export_configs">Yapılandırmaları dışa aktar</string>
|
||||
<string name="location_services_required">Gerekli konum hizmetleri</string>
|
||||
<string name="background_location_required">Arka plan konumu gerekli</string>
|
||||
<string name="precise_location_required">Kesin konum gerekli</string>
|
||||
<string name="unknown_error">Bilinmeyen bir hata oluştu</string>
|
||||
<string name="exported_configs_message">Yapılandırmalar indirilenler\'e aktarıldı</string>
|
||||
<string name="tunnel_on_wifi">Güvenilmeyen kablosuz internet bağlantısında tünel</string>
|
||||
<string name="my_email" translatable="false">support@zaneschepke.com</string>
|
||||
<string name="email_subject">WG Tunnel Desteği</string>
|
||||
<string name="email_chooser">Bir e-posta gönderin…</string>
|
||||
<string name="go">git</string>
|
||||
<string name="docs_description">Belgeleri oku</string>
|
||||
<string name="discord_description">Topluluğa katıl</string>
|
||||
<string name="email_description">Bana e-posta gönder</string>
|
||||
<string name="support_help_text">Sorun yaşıyorsanız, iyileştirme fikirleriniz varsa veya sadece etkileşimde bulunmak istiyorsanız, aşağıdaki kaynaklar mevcuttur:</string>
|
||||
<string name="kernel">Çekirdek</string>
|
||||
<string name="use_kernel">Çekirdek modülünü kullan</string>
|
||||
<string name="error_ssid_exists">SSID zaten var</string>
|
||||
<string name="error_root_denied">Kök kabuğu reddedildi</string>
|
||||
<string name="error_no_file_explorer">Yüklü dosya gezgini yok</string>
|
||||
<string name="error_invalid_code">Geçersiz QR kodu</string>
|
||||
<string name="error_none">Hata yok</string>
|
||||
<string name="location_services_missing_message">Uygulama, cihazınızda etkinleştirilen herhangi bir konum hizmeti algılamıyor. Cihaza bağlı olarak bu, güvenilmeyen Wi-Fi özelliğinin Wi-Fi adını okuyamamasına neden olabilir. Yine de devam etmek ister misiniz?</string>
|
||||
<string name="auto_tunnel_title">Otomatik Tünel Hizmeti</string>
|
||||
<string name="delete_tunnel">Tüneli sil</string>
|
||||
<string name="delete_tunnel_message">Bu tüneli silmek istediğinizden emin misiniz?</string>
|
||||
<string name="yes">Evet</string>
|
||||
<string name="resume">Devam et</string>
|
||||
<string name="pause">Duraklat</string>
|
||||
<string name="paused">duraklatıldı</string>
|
||||
<string name="active">aktif</string>
|
||||
<string name="tunneling_apps">Tünellenen uygulamalar</string>
|
||||
<string name="included">dahil edildi</string>
|
||||
<string name="excluded">hariç tutuldu</string>
|
||||
<string name="all">tümü</string>
|
||||
<string name="always_on_disabled">Her zaman açık VPN bir tünel başlatmaya çalıştı, ancak bu özellik ayarlarda devre dışı bırakıldı.</string>
|
||||
<string name="no_email_detected">E-posta uygulaması algılanmadı</string>
|
||||
<string name="no_browser_detected">Tarayıcı algılanmadı</string>
|
||||
<string name="logs_saved">İndirilenlere kaydedilen günlükler</string>
|
||||
<string name="open_issue">Bir sorun bildir</string>
|
||||
<string name="read_logs">Günlükleri oku</string>
|
||||
<string name="auto">(Otomatik)</string>
|
||||
<string name="config_parse_error">Yapılandırma kaydedilemedi</string>
|
||||
<string name="incorrect_pin">PIN kodu yanlış</string>
|
||||
<string name="pin_created">Pin başarıyla oluşturuldu</string>
|
||||
<string name="enter_pin">PIN kodunuzu girin</string>
|
||||
<string name="create_pin">PIN kodu oluştur</string>
|
||||
<string name="enable_app_lock">Uygulama kilidini etkinleştir</string>
|
||||
<string name="restart_on_ping">Ping başarısız olduğunda yeniden başlat (beta)</string>
|
||||
<string name="mobile_data_tunnel">Mobil veri tüneli olarak ayarla</string>
|
||||
<string name="set_primary_tunnel">Birincil tünel olarak ayarla</string>
|
||||
<string name="use_tunnel_on_wifi_name">Wi-Fi adında tünel kullan</string>
|
||||
<string name="no_wifi_names_configured">Bu tünel için yapılandırılmış Wi-Fi adı yok</string>
|
||||
<string name="general">Genel</string>
|
||||
<string name="edit_tunnel">Tüneli düzenle</string>
|
||||
<string name="disabled">Devre dışı</string>
|
||||
<string name="auto_on">Otomatik ayarlamayı sürdür</string>
|
||||
<string name="auto_off">Otomatik ayarlamayı duraklat</string>
|
||||
<string name="auto_tun_on">Otomatik tüneli sürdür</string>
|
||||
<string name="auto_tun_off">Otomatik tüneli duraklat</string>
|
||||
<string name="version">Sürüm</string>
|
||||
<string name="mode">Mod</string>
|
||||
<string name="userspace">Kullanıcı alanı</string>
|
||||
<string name="settings">Ayarlar</string>
|
||||
<string name="support">Destek</string>
|
||||
</resources>
|
||||
@@ -1,11 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</color>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="teal_200">#FF03DAC5</color>
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black_background">#FF1c1b20</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_channel_background">#1D1A20</color>
|
||||
</resources>
|
||||
@@ -4,32 +4,24 @@
|
||||
<string name="vpn_channel_name">VPN Notification Channel</string>
|
||||
<string name="watcher_channel_id">Watcher Channel</string>
|
||||
<string name="watcher_channel_name">Watcher Notification Channel</string>
|
||||
<string name="foreground_file">FOREGROUND_FILE</string>
|
||||
<string name="github_url" translatable="false">https://github.com/zaneschepke/wgtunnel/issues</string>
|
||||
<string name="docs_url" translatable="false">https://zaneschepke.com/wgtunnel-docs/overview.html</string>
|
||||
<string name="privacy_policy_url" translatable="false">https://zaneschepke.com/wgtunnel-docs/privacypolicy.html</string>
|
||||
<string name="error_file_extension">File is not a .conf or .zip</string>
|
||||
<string name="turn_off_tunnel">Action requires tunnel off</string>
|
||||
<string name="no_tunnels">No tunnels added yet!</string>
|
||||
<string name="tunnel_exists">Tunnel name already exists</string>
|
||||
<string name="discord_url" translatable="false">https://discord.gg/rbRRNh6H7V</string>
|
||||
<string name="watcher_notification_title">Watcher Service</string>
|
||||
<string name="watcher_notification_text_active">Monitoring network state changes: active</string>
|
||||
<string name="watcher_notification_text_paused">Monitoring network state changes: paused</string>
|
||||
<string name="tunnel_start_title">VPN connected</string>
|
||||
<string name="tunnel_start_text">Connected to tunnel</string>
|
||||
<string name="vpn_permission_required">VPN permission is required for the app to work properly. If this permission is not launching, please disable \"Always-on VPN\" in your phone settings for the official WireGuard mobile app and try again.</string>
|
||||
<string name="notification_permission_required">Notifications permission required.</string>
|
||||
<string name="open_settings">Open Settings</string>
|
||||
<string name="add_trusted_ssid">Add trusted wifi name</string>
|
||||
<string name="tunnels">Tunnels</string>
|
||||
<string name="enable_auto_tunnel">Start auto-tunneling</string>
|
||||
<string name="disable_auto_tunnel">Stop auto-tunneling</string>
|
||||
<string name="tunnel_mobile_data">Tunnel on mobile data</string>
|
||||
<string name="background_location_reason">\"Allow all the time\" location permission is required for retrieving Wi-Fi SSID in the background. Permission is needed for this feature.</string>
|
||||
<string name="location_permission_reason">Location permission is required for this feature to work properly.</string>
|
||||
<string name="one_tunnel_required">At least one tunnel required to use this feature</string>
|
||||
<string name="retry">"Retry"</string>
|
||||
<string name="privacy_policy">View Privacy Policy</string>
|
||||
<string name="okay">Okay</string>
|
||||
<string name="tunnel_on_ethernet">Tunnel on ethernet</string>
|
||||
@@ -38,12 +30,10 @@
|
||||
<string name="thank_you">Thank you for using WG Tunnel!</string>
|
||||
<string name="trusted_ssid_empty_description">Enter SSID</string>
|
||||
<string name="trusted_ssid_value_description">Submit SSID</string>
|
||||
<string name="config_validation" translatable="false">[Interface]</string>
|
||||
<string name="add_tunnels_text">Add from file or zip</string>
|
||||
<string name="open_file">File Open</string>
|
||||
<string name="add_from_qr">Add from QR code</string>
|
||||
<string name="qr_scan">QR Scan</string>
|
||||
<string name="tunnel_edit">Tunnel Edit</string>
|
||||
<string name="tunnel_name">Tunnel Name</string>
|
||||
<string name="add_tunnel">Add Tunnel</string>
|
||||
<string name="exclude">Exclude</string>
|
||||
@@ -55,34 +45,18 @@
|
||||
<string name="no_thanks">No thanks</string>
|
||||
<string name="turn_on">Turn on</string>
|
||||
<string name="map">Map</string>
|
||||
<string name="bad_config">Bad config. Please try again.</string>
|
||||
<string name="config_interface">Interface</string>
|
||||
<string name="public_key">Public key</string>
|
||||
<string name="barcode_downloading">Waiting for the Barcode UI module to be downloaded.</string>
|
||||
<string name="barcode_downloading_message">Barcode module downloading. Try again.</string>
|
||||
<string name="addresses">Addresses</string>
|
||||
<string name="dns_servers">DNS servers</string>
|
||||
<string name="mtu">MTU</string>
|
||||
<string name="peer">Peer</string>
|
||||
<string name="allowed_ips">Allowed IPs</string>
|
||||
<string name="endpoint">Endpoint</string>
|
||||
<string name="transfer">Transfer</string>
|
||||
<string name="last_handshake">Last handshake</string>
|
||||
<string name="name">Name</string>
|
||||
<string name="restart">Restart Tunnel</string>
|
||||
<string name="vpn_connection_failed">Connection failed</string>
|
||||
<string name="failed_connection_to">Failed connection to -</string>
|
||||
<string name="initial_connection_failure_message">Attempting to connect to server after 30 seconds of no response.</string>
|
||||
<string name="lost_connection_failure_message">Attempting to reconnect to server after more than one minute of no response.</string>
|
||||
<string name="always_on_vpn_support">Allow Always-On VPN </string>
|
||||
<string name="select_tunnel_message">Please select a tunnel first</string>
|
||||
<string name="location_services_not_detected">Location Services Not Detected</string>
|
||||
<string name="check_again">Check again</string>
|
||||
<string name="detecting_location_services_disabled">Detecting Location Services disabled</string>
|
||||
<string name="precise_location_message">This feature requires precise location to access Wi-Fi SSID name. Please enable precise location here or in the app settings.</string>
|
||||
<string name="request">Request</string>
|
||||
<string name="toggle_vpn">Toggle VPN</string>
|
||||
<string name="no_tunnel_available">No tunnels available</string>
|
||||
<string name="hint_search_packages">Search packages</string>
|
||||
<string name="clear_icon">Clear Icon</string>
|
||||
<string name="search_icon">Search Icon</string>
|
||||
@@ -90,13 +64,9 @@
|
||||
<string name="vpn_starting">VPN starting</string>
|
||||
<string name="db_name">wg-tunnel-db</string>
|
||||
<string name="scanning_qr">Scanning for QR</string>
|
||||
<string name="qr_result_failed">QR scan failed</string>
|
||||
<string name="none">No trusted wifi names</string>
|
||||
<string name="never">Never</string>
|
||||
<string name="stream_failed">Failed to open file stream.</string>
|
||||
<string name="other">Other</string>
|
||||
<string name="auto_tunneling">Auto-tunneling</string>
|
||||
<string name="select_tunnel">Select tunnel to use</string>
|
||||
<string name="vpn_on">VPN on</string>
|
||||
<string name="vpn_off">VPN off</string>
|
||||
<string name="default_vpn_on">Primary VPN on</string>
|
||||
@@ -124,7 +94,6 @@
|
||||
<string name="error_authorization_failed">Failed to authorize</string>
|
||||
<string name="enabled_app_shortcuts">Enable app shortcuts</string>
|
||||
<string name="export_configs">Export configs</string>
|
||||
<string name="battery_saver">Battery saver (beta)</string>
|
||||
<string name="location_services_required">Location services required</string>
|
||||
<string name="background_location_required">Background location required</string>
|
||||
<string name="precise_location_required">Precise location required</string>
|
||||
@@ -135,7 +104,7 @@
|
||||
<string name="email_subject">WG Tunnel Support</string>
|
||||
<string name="email_chooser">Send an email…</string>
|
||||
<string name="go">go</string>
|
||||
<string name="docs_description">Read the docs (WIP)</string>
|
||||
<string name="docs_description">Read the docs</string>
|
||||
<string name="discord_description">Join the community</string>
|
||||
<string name="email_description">Send me an email</string>
|
||||
<string name="support_help_text">If you are experiencing issues, have improvement ideas, or just want to engage, the following resources are available:</string>
|
||||
@@ -144,11 +113,8 @@
|
||||
<string name="error_ssid_exists">SSID already exists</string>
|
||||
<string name="error_root_denied">Root shell denied</string>
|
||||
<string name="error_no_file_explorer">No file explorer installed</string>
|
||||
<string name="error_no_scan">No code scanned</string>
|
||||
<string name="error_invalid_code">Invalid QR code</string>
|
||||
<string name="error_none">No error</string>
|
||||
<string name="error_file_read">Failed to read file</string>
|
||||
<string name="location_service_missing">Location Services Not Detected</string>
|
||||
<string name="location_services_missing_message">The app is not detecting any location services enabled on your device. Depending on the device, this could cause the untrusted wifi feature to fail to read the wifi name. Would you like to continue anyways?</string>
|
||||
<string name="auto_tunnel_title">Auto-tunnel Service</string>
|
||||
<string name="delete_tunnel">Delete tunnel</string>
|
||||
@@ -182,10 +148,14 @@
|
||||
<string name="no_wifi_names_configured">No wifi names configured for this tunnel</string>
|
||||
<string name="general">General</string>
|
||||
<string name="edit_tunnel">Edit tunnel</string>
|
||||
<string name="tunnel">Tunnel</string>
|
||||
<string name="disabled">disabled</string>
|
||||
<string name="auto_on">Resume auto tun</string>
|
||||
<string name="auto_off">Pause auto tun</string>
|
||||
<string name="auto_tun_on">Resume auto-tunnel</string>
|
||||
<string name="auto_tun_off">Pause auto-tunnel</string>
|
||||
<string name="version">Version</string>
|
||||
<string name="mode">Mode</string>
|
||||
<string name="userspace">Userspace</string>
|
||||
<string name="settings">Settings</string>
|
||||
<string name="support">Support</string>
|
||||
</resources>
|
||||
@@ -1,7 +1,7 @@
|
||||
object Constants {
|
||||
const val VERSION_NAME = "3.4.0"
|
||||
const val VERSION_NAME = "3.4.3-alpha"
|
||||
const val JVM_TARGET = "17"
|
||||
const val VERSION_CODE = 34000
|
||||
const val VERSION_CODE = 34201
|
||||
const val TARGET_SDK = 34
|
||||
const val MIN_SDK = 26
|
||||
const val APP_ID = "com.zaneschepke.wireguardautotunnel"
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
Verbesserungen:
|
||||
- Berechtigungsfehler auf Android Versionen vor 9 behoben
|
||||
- Andere Optimierungen
|
||||
@@ -0,0 +1,5 @@
|
||||
Verbesserungen:
|
||||
- Tunnelstatistiken zum Hauptbildschirm hinzugefügt
|
||||
- Navigation der Einstellungen auf AndroidTV verbessert
|
||||
- Vibration von Benachrichtigungen entfernt
|
||||
- Verschiedene andere Fehlerbehebungen
|
||||
@@ -0,0 +1,5 @@
|
||||
Verbesserungen:
|
||||
- Unterstützung für Tunnelung nur bei Verwendung von Mobilen Daten
|
||||
- Verbesserungen der Support Oberfläche
|
||||
- Aktualisierung der Ressourcenlinks
|
||||
- Verschiedene andere Fehlerbehebungen
|
||||
@@ -0,0 +1,5 @@
|
||||
Verbesserungen:
|
||||
- Grundlegende Unterstützung für WireGuard Kernelmodus hinzugefügt
|
||||
- Verbesserung des Positionsanfrage
|
||||
- Behebung eines Berechtigungsfehlers bei Auto-Tunneln
|
||||
- Verschiedene andere GUI Fehlerbehebungen
|
||||
@@ -0,0 +1,2 @@
|
||||
Fehlerbehebungen:
|
||||
- Android 14 Vordergrundberechtigungen
|
||||
@@ -0,0 +1,7 @@
|
||||
Verbesserungen:
|
||||
- Refaktorierung der Zustandsverwaltung
|
||||
- Verbesserung der AndroidTV Navigation
|
||||
- Verbesserung der Auto-Tunnel Effizienz
|
||||
- Navigation verbessert
|
||||
- Auto-Tunnel Pausefunktion
|
||||
- Viele Fehlerbehebungen
|
||||
@@ -0,0 +1,13 @@
|
||||
Funktionen
|
||||
|
||||
- Hinzufügen von Tunneln über .conf Dateien, Zip, Manuelle Eingabe oder QR Codes
|
||||
- Automatische Verbindung zum VPN basierend auf der Wifi-SSID, Ethernet und mobilen Daten
|
||||
- Geteilter Tunnel für Anwendungen mit Suche
|
||||
- Unterstützung für Wireguard Userspace- und Kernel-modus
|
||||
- Always-On VPN Unterstützung
|
||||
- Export von Tunneln ins Zip Format
|
||||
- Quicktiles zum aktivieren/deaktivieren der VPN Verbindung
|
||||
- Feste Shortcuts für den Haupttunnel für automatische Integration
|
||||
- Intent basierten Automationssupport für alle Tunnel
|
||||
- Automatischer Servicestart nach Geräteneustart
|
||||
- Akkuerhaltungsfunktionen
|
||||
@@ -0,0 +1 @@
|
||||
Eine alternative VPN Client App für Wireguard mit zusätzlichen Funktionen
|
||||
@@ -0,0 +1 @@
|
||||
WG Tunnel
|
||||
@@ -0,0 +1,5 @@
|
||||
What's new:
|
||||
- Improved auto tunnel reliability
|
||||
- Improved tile sync
|
||||
- Added AndroidTV assets
|
||||
- Added apk fingerprint
|
||||
@@ -0,0 +1,5 @@
|
||||
What's new:
|
||||
- Fix stop tunnel regression
|
||||
- Add logs obfuscation
|
||||
- Add hide FAB on scroll
|
||||
- Add Turkish localization
|
||||
@@ -0,0 +1,2 @@
|
||||
What's new:
|
||||
- AmneziaWG support
|
||||
@@ -0,0 +1,3 @@
|
||||
Mejoras:
|
||||
- Corrección de fallo de permisos en < Android 9
|
||||
- Otras optimizaciones
|
||||
@@ -0,0 +1,5 @@
|
||||
Mejoras:
|
||||
- Añadidas estadísticas del túnel a la pantalla principal
|
||||
- Navegación mejorada en la pantalla de ajustes para AndroidTV
|
||||
- Vibración de notificación quitada
|
||||
- Otras correcciones
|
||||
@@ -0,0 +1,5 @@
|
||||
Mejoras:
|
||||
- Compatibilidad de túnel-automático cuando solo para datos móviles
|
||||
- UI de la pantalla de ayuda mojorada
|
||||
- Enlaces de recursos mejorados
|
||||
- Otras correcciones
|
||||
@@ -0,0 +1,2 @@
|
||||
Mejoras:
|
||||
- Añadida compatiblidad básica de Kernel WireGuard
|
||||
@@ -0,0 +1,2 @@
|
||||
Correcciones:
|
||||
- Permisos en primer plano en Android 14
|
||||
@@ -0,0 +1,13 @@
|
||||
Características:
|
||||
|
||||
- Añadir túneles vía .conf file, zip, manualmente, o código QR
|
||||
- Conexión automática a la VPN basado en el SSID Wi-Fi, ethernet, o datos móviles
|
||||
- División de túnel por aplicacióno con búsqueda
|
||||
- Compatibilidad WireGuard para modos kernel y userspace
|
||||
- Compatibilidad con VPN Siempre-Activada
|
||||
- Exportar túmeles como zip
|
||||
- Añadido interruptor VPN en el Centro de Control
|
||||
- Accesos directos estáticos para túnel principal para intergración con apps de automatización
|
||||
- Intents de apps de automatización para todos los túneles
|
||||
- Inicio automático del servicio tras reinicio
|
||||
- Medidas para ahorro de batería
|
||||
@@ -0,0 +1 @@
|
||||
Una app cliente VPN alternativa para WireGuard con características adicionales
|
||||
@@ -0,0 +1 @@
|
||||
WG Tunnel
|
||||
@@ -0,0 +1,13 @@
|
||||
Возможности
|
||||
|
||||
- Добавляйте туннели через файл .conf, zip, ввод вручную или QR-код
|
||||
- Автоматическое подключение к VPN основываясь на SSID Wi-Fi, подключению по Ethernet или мобильных данных
|
||||
- Разделение туннелирования по приложениям с поиском
|
||||
- Поддержка WireGuard для режимов ядра и пользовательского пространства
|
||||
- Поддержка режима VPN Всегда-Включено
|
||||
- Экспорт туннелей в zip
|
||||
- Поддержка быстрой плитки для переключения VPN
|
||||
- Поддержка статических ярлыков для основного туннеля для интеграции автоматизации
|
||||
- Поддержка автоматизации через intent для всех туннелей
|
||||
- Автоматический перезапуск службы после перезагрузки
|
||||
- Меры по сохранению аккумулятора
|
||||
@@ -0,0 +1 @@
|
||||
Альтернативный VPN-клиент для WireGuard с дополнительными функциями
|
||||
@@ -0,0 +1 @@
|
||||
WG Тунель
|
||||
@@ -0,0 +1,13 @@
|
||||
Özellikler
|
||||
|
||||
- .conf dosyası, zip, manuel giriş veya QR kodu aracılığıyla tüneller ekleme
|
||||
- Wi-Fi SSID'ye, ethernet'e veya mobil veriye dayalı VPN'ye otomatik bağlanma
|
||||
- Uygulama bazında split tunneling ve arama desteği
|
||||
- Kernel ve kullanıcı alanı modları için WireGuard desteği
|
||||
- Her zaman açık VPN desteği
|
||||
- Tünelleri zip olarak dışa aktarma
|
||||
- VPN geçişleri için hızlı kısayol desteği
|
||||
- Otomasyon entegrasyonu için birincil tünel için statik kısayollar desteği
|
||||
- Tüm tüneller için Intent otomasyon desteği
|
||||
- Yeniden başlatma sonrası otomatik olarak servisi yeniden başlatma
|
||||
- Batarya koruma önlemleri
|
||||
@@ -0,0 +1 @@
|
||||
WireGuard için ek özelliklere sahip alternatif bir VPN istemci uygulaması
|
||||
@@ -0,0 +1 @@
|
||||
WG Tunnel
|
||||
@@ -1,6 +1,7 @@
|
||||
[versions]
|
||||
accompanist = "0.34.0"
|
||||
activityCompose = "1.8.2"
|
||||
amneziawgAndroid = "1.1.0"
|
||||
androidx-junit = "1.1.5"
|
||||
appcompat = "1.6.1"
|
||||
biometricKtx = "1.2.0-alpha05"
|
||||
@@ -20,7 +21,7 @@ pinLockCompose = "1.0.3"
|
||||
roomVersion = "2.6.1"
|
||||
timber = "5.0.1"
|
||||
tunnel = "1.0.20230706"
|
||||
androidGradlePlugin = "8.3.1"
|
||||
androidGradlePlugin = "8.4.0-rc02"
|
||||
kotlin = "1.9.23"
|
||||
ksp = "1.9.23-1.0.19"
|
||||
composeBom = "2024.03.00"
|
||||
@@ -41,6 +42,7 @@ accompanist-flowlayout = { module = "com.google.accompanist:accompanist-flowlayo
|
||||
accompanist-permissions = { module = "com.google.accompanist:accompanist-permissions", version.ref = "accompanist" }
|
||||
|
||||
#room
|
||||
amneziawg-android = { module = "com.zaneschepke:amneziawg-android", version.ref = "amneziawgAndroid" }
|
||||
androidx-biometric-ktx = { module = "androidx.biometric:biometric-ktx", version.ref = "biometricKtx" }
|
||||
androidx-core = { module = "androidx.core:core", version.ref = "coreKtx" }
|
||||
androidx-core-google-shortcuts = { module = "androidx.core:core-google-shortcuts", version.ref = "coreGoogleShortcuts" }
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
#Wed Oct 11 22:39:21 EDT 2023
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
|
||||
distributionSha256Sum=3e1af3ae886920c3ac87f7a91f816c0c7c436f276a6eefdb3da152100fef72ae
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
|
||||
distributionSha256Sum=9631d53cf3e74bfa726893aee1f8994fee4e060c401335946dba2156f440f24c
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
@@ -3,14 +3,29 @@ package com.zaneschepke.logcatter
|
||||
import com.zaneschepke.logcatter.model.LogMessage
|
||||
|
||||
object Logcatter {
|
||||
fun logs(callback: (input: LogMessage) -> Unit) {
|
||||
|
||||
private val findKeyRegex = """[A-Za-z0-9+/]{42}[AEIMQUYcgkosw480]=""".toRegex()
|
||||
private val findIpv6AddressRegex = """(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))""".toRegex()
|
||||
private val findIpv4AddressRegex = """((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}""".toRegex()
|
||||
private val findTunnelNameRegex = """(?<=tunnel ).*?(?= UP| DOWN)""".toRegex()
|
||||
|
||||
|
||||
fun logs(callback: (input: LogMessage) -> Unit, obfuscator: (log : String) -> String = { log -> this.obfuscator(log)}){
|
||||
clear()
|
||||
Runtime.getRuntime().exec("logcat -v epoch")
|
||||
.inputStream
|
||||
.bufferedReader()
|
||||
.useLines { lines ->
|
||||
lines.forEach { callback(LogMessage.from(it)) }
|
||||
lines.forEach { callback(LogMessage.from(obfuscator(it))) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun obfuscator(log : String) : String {
|
||||
return findKeyRegex.replace(log, "<crypto-key>").let { first ->
|
||||
findIpv6AddressRegex.replace(first, "<ipv6-address>").let { second ->
|
||||
findTunnelNameRegex.replace(second, "<tunnel>")
|
||||
}
|
||||
}.let{ last -> findIpv4AddressRegex.replace(last,"<ipv4-address>") }
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
|
||||
Reference in New Issue
Block a user