From b9a9a407e9b14ebd1260ae1b80d80ed974beffa8 Mon Sep 17 00:00:00 2001 From: pierre Date: Wed, 6 Sep 2023 18:36:01 +0200 Subject: [PATCH 1/2] init --- nym-vpn/android/.gitignore | 71 +++ nym-vpn/android/.gitkeep | 0 nym-vpn/android/LICENSE | 21 + nym-vpn/android/README.md | 42 ++ nym-vpn/android/app/.gitignore | 2 + nym-vpn/android/app/build.gradle.kts | 159 +++++++ .../android/app/objectbox-models/default.json | 99 +++++ .../app/objectbox-models/default.json.bak | 94 ++++ nym-vpn/android/app/proguard-rules.pro | 21 + .../ExampleInstrumentedTest.kt | 24 + .../android/app/src/main/AndroidManifest.xml | 115 +++++ .../app/src/main/ic_launcher-playstore.png | Bin 0 -> 39338 bytes .../wireguardautotunnel/Constants.kt | 6 + .../WireGuardAutoTunnel.kt | 27 ++ .../wireguardautotunnel/module/BoxModule.kt | 40 ++ .../module/RepositoryModule.kt | 25 ++ .../module/ServiceModule.kt | 29 ++ .../module/TunnelModule.kt | 31 ++ .../receiver/BootReceiver.kt | 39 ++ .../receiver/NotificationActionReceiver.kt | 39 ++ .../repository/Repository.kt | 16 + .../repository/SettingsBox.kt | 63 +++ .../repository/TunnelBox.kt | 57 +++ .../service/foreground/Action.kt | 6 + .../service/foreground/ForegroundService.kt | 64 +++ .../service/foreground/ServiceManager.kt | 90 ++++ .../service/foreground/ServiceState.kt | 6 + .../WireGuardConnectivityWatcherService.kt | 210 +++++++++ .../foreground/WireGuardTunnelService.kt | 154 +++++++ .../service/network/BaseNetworkService.kt | 117 +++++ .../service/network/MobileDataService.kt | 10 + .../service/network/NetworkService.kt | 10 + .../service/network/NetworkStatus.kt | 10 + .../service/network/WifiService.kt | 10 + .../notification/NotificationService.kt | 21 + .../notification/WireGuardNotification.kt | 77 ++++ .../service/shortcut/ShortcutsActivity.kt | 28 ++ .../service/shortcut/ShortcutsManager.kt | 73 +++ .../service/tile/TunnelControlTile.kt | 142 ++++++ .../service/tunnel/HandshakeStatus.kt | 14 + .../service/tunnel/VpnService.kt | 18 + .../service/tunnel/WireGuardTunnel.kt | 131 ++++++ .../service/tunnel/model/Settings.kt | 15 + .../service/tunnel/model/TunnelConfig.kt | 89 ++++ .../wireguardautotunnel/ui/MainActivity.kt | 201 +++++++++ .../wireguardautotunnel/ui/Routes.kt | 36 ++ .../wireguardautotunnel/ui/ViewState.kt | 9 + .../ui/common/ClickableIconButton.kt | 31 ++ .../common/PermissionRequestFailedScreen.kt | 35 ++ .../ui/common/RowListItem.kt | 55 +++ .../ui/common/SearchBar.kt | 80 ++++ .../ui/common/navigation/BottomNavBar.kt | 42 ++ .../ui/common/navigation/BottomNavItem.kt | 9 + .../ui/screens/config/ConfigScreen.kt | 241 ++++++++++ .../ui/screens/config/ConfigViewModel.kt | 152 +++++++ .../ui/screens/detail/DetailScreen.kt | 139 ++++++ .../ui/screens/detail/DetailViewModel.kt | 45 ++ .../ui/screens/main/MainScreen.kt | 336 ++++++++++++++ .../ui/screens/main/MainViewModel.kt | 179 ++++++++ .../ui/screens/settings/SettingsScreen.kt | 415 ++++++++++++++++++ .../ui/screens/settings/SettingsViewModel.kt | 124 ++++++ .../ui/screens/support/SupportScreen.kt | 83 ++++ .../wireguardautotunnel/ui/theme/Color.kt | 17 + .../wireguardautotunnel/ui/theme/Theme.kt | 80 ++++ .../ui/theme/TransparentSystemBars.kt | 22 + .../wireguardautotunnel/ui/theme/Type.kt | 34 ++ .../wireguardautotunnel/util/NumberUtils.kt | 25 ++ .../app/src/main/res/drawable/discord.xml | 10 + .../app/src/main/res/drawable/github.xml | 12 + .../res/drawable/ic_launcher_background.xml | 170 +++++++ .../res/drawable/ic_launcher_foreground.xml | 30 ++ .../app/src/main/res/drawable/shield.xml | 5 + .../app/src/main/res/drawable/vpn_off.xml | 5 + .../app/src/main/res/drawable/vpn_on.xml | 5 + .../main/res/mipmap-anydpi-v26/ic_banner.xml | 5 + .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 2004 bytes .../mipmap-hdpi/ic_launcher_foreground.webp | Bin 0 -> 2936 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 3568 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 1268 bytes .../mipmap-mdpi/ic_launcher_foreground.webp | Bin 0 -> 1926 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 2242 bytes .../src/main/res/mipmap-xhdpi/ic_banner.png | Bin 0 -> 3578 bytes .../res/mipmap-xhdpi/ic_banner_foreground.png | Bin 0 -> 3770 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 2728 bytes .../mipmap-xhdpi/ic_launcher_foreground.webp | Bin 0 -> 3956 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 5030 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 4246 bytes .../mipmap-xxhdpi/ic_launcher_foreground.webp | Bin 0 -> 6154 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 7718 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 5854 bytes .../ic_launcher_foreground.webp | Bin 0 -> 8314 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 10402 bytes .../app/src/main/res/values/colors.xml | 11 + .../main/res/values/ic_banner_background.xml | 4 + .../res/values/ic_launcher_background.xml | 4 + .../app/src/main/res/values/strings.xml | 90 ++++ .../app/src/main/res/values/themes.xml | 6 + .../app/src/main/res/xml/backup_rules.xml | 13 + .../main/res/xml/data_extraction_rules.xml | 19 + .../wireguardautotunnel/ExampleUnitTest.kt | 17 + nym-vpn/android/build.gradle.kts | 19 + nym-vpn/android/gradle.properties | 25 ++ .../android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + nym-vpn/android/gradlew | 185 ++++++++ nym-vpn/android/gradlew.bat | 89 ++++ nym-vpn/android/settings.gradle.kts | 18 + 109 files changed, 5463 insertions(+) create mode 100644 nym-vpn/android/.gitignore delete mode 100644 nym-vpn/android/.gitkeep create mode 100644 nym-vpn/android/LICENSE create mode 100644 nym-vpn/android/README.md create mode 100644 nym-vpn/android/app/.gitignore create mode 100644 nym-vpn/android/app/build.gradle.kts create mode 100644 nym-vpn/android/app/objectbox-models/default.json create mode 100644 nym-vpn/android/app/objectbox-models/default.json.bak create mode 100644 nym-vpn/android/app/proguard-rules.pro create mode 100644 nym-vpn/android/app/src/androidTest/java/com/zaneschepke/wireguardautotunnel/ExampleInstrumentedTest.kt create mode 100644 nym-vpn/android/app/src/main/AndroidManifest.xml create mode 100644 nym-vpn/android/app/src/main/ic_launcher-playstore.png create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/Constants.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/BoxModule.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/RepositoryModule.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/ServiceModule.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/TunnelModule.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/NotificationActionReceiver.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/Repository.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/SettingsBox.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/TunnelBox.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/Action.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ForegroundService.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceManager.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceState.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/BaseNetworkService.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/MobileDataService.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/NetworkService.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/NetworkStatus.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/WifiService.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/notification/NotificationService.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/notification/WireGuardNotification.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsActivity.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsManager.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/HandshakeStatus.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/VpnService.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/WireGuardTunnel.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/Settings.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/TunnelConfig.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/MainActivity.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/Routes.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/ViewState.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/ClickableIconButton.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/PermissionRequestFailedScreen.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/RowListItem.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/SearchBar.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/navigation/BottomNavBar.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/navigation/BottomNavItem.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigScreen.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigViewModel.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/detail/DetailScreen.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/detail/DetailViewModel.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsViewModel.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/SupportScreen.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/Color.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/Theme.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/TransparentSystemBars.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/Type.kt create mode 100644 nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/util/NumberUtils.kt create mode 100644 nym-vpn/android/app/src/main/res/drawable/discord.xml create mode 100644 nym-vpn/android/app/src/main/res/drawable/github.xml create mode 100644 nym-vpn/android/app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 nym-vpn/android/app/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 nym-vpn/android/app/src/main/res/drawable/shield.xml create mode 100644 nym-vpn/android/app/src/main/res/drawable/vpn_off.xml create mode 100644 nym-vpn/android/app/src/main/res/drawable/vpn_on.xml create mode 100644 nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_banner.xml create mode 100644 nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_banner.png create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_banner_foreground.png create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 nym-vpn/android/app/src/main/res/values/colors.xml create mode 100644 nym-vpn/android/app/src/main/res/values/ic_banner_background.xml create mode 100644 nym-vpn/android/app/src/main/res/values/ic_launcher_background.xml create mode 100644 nym-vpn/android/app/src/main/res/values/strings.xml create mode 100644 nym-vpn/android/app/src/main/res/values/themes.xml create mode 100644 nym-vpn/android/app/src/main/res/xml/backup_rules.xml create mode 100644 nym-vpn/android/app/src/main/res/xml/data_extraction_rules.xml create mode 100644 nym-vpn/android/app/src/test/java/com/zaneschepke/wireguardautotunnel/ExampleUnitTest.kt create mode 100644 nym-vpn/android/build.gradle.kts create mode 100644 nym-vpn/android/gradle.properties create mode 100644 nym-vpn/android/gradle/wrapper/gradle-wrapper.jar create mode 100644 nym-vpn/android/gradle/wrapper/gradle-wrapper.properties create mode 100755 nym-vpn/android/gradlew create mode 100644 nym-vpn/android/gradlew.bat create mode 100644 nym-vpn/android/settings.gradle.kts diff --git a/nym-vpn/android/.gitignore b/nym-vpn/android/.gitignore new file mode 100644 index 0000000000..31caa0cedf --- /dev/null +++ b/nym-vpn/android/.gitignore @@ -0,0 +1,71 @@ +# Built application files +*.apk +*.aar +*.ap_ +*.aab +# Files for the ART/Dalvik VM +*.dex +# Java class files +*.class +# Generated files +bin/ +gen/ +out/ +release/ +build/ +# Gradle files +.gradle/ +# Local configuration file (sdk path, etc) +local.properties +# Proguard folder generated by Eclipse +proguard/ +# Log Files +*.log +# Android Studio Navigation editor temp files +.navigation/ +# Android Studio captures folder +captures/ +# IntelliJ +*.iml +.idea/ +# .idea/workspace.xml +# .idea/tasks.xml +# .idea/gradle.xml +# .idea/assetWizardSettings.xml +# .idea/dictionaries +.idea/libraries +# Android Studio 3 in .gitignore file. +.idea/caches +.idea/modules.xml +# Comment next line if keeping position of elements in Navigation Editor is relevant for you +.idea/navEditor.xml +# Keystore files +# Uncomment the following lines if you do not want to check your keystore files in. +*.jks +*.keystore +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild +.cxx/ +# Freeline +freeline.py +freeline/ +freeline_project_description.json +# fastlane +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots +fastlane/test_output +fastlane/readme.md +# Version control +vcs.xml +# lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +# lint/reports/ +# MacOS +.DS_Store +# App Specific cases +app/release/output.json +.idea/codeStyles/ diff --git a/nym-vpn/android/.gitkeep b/nym-vpn/android/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/nym-vpn/android/LICENSE b/nym-vpn/android/LICENSE new file mode 100644 index 0000000000..51f3844dba --- /dev/null +++ b/nym-vpn/android/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 NymConnect + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/nym-vpn/android/README.md b/nym-vpn/android/README.md new file mode 100644 index 0000000000..e4a334e993 --- /dev/null +++ b/nym-vpn/android/README.md @@ -0,0 +1,42 @@ +## NymConnect for Android + +### Prerequisites + +_TODO_ + +### Getting started + +[Install](https://developer.android.com/studio/install) Android Studio and open +the project.\ +Setup an android emulator using AVD.\ +[Run](https://developer.android.com/studio/run/emulator) the project. + +**⚠ NOTE**: be sure +to [set](https://developer.android.com/studio/run#changing-variant) +the build variant to `x86_64Debug` when running on emulator + +### Features + +* Add tunnels via .conf file +* Auto connect to VPN based on Wi-Fi SSID +* Split tunneling by application with search +* Always-on VPN for Android support +* Quick tile support for vpn toggling +* Dynamic shortcuts support for automation integration +* Configurable Trusted Network list +* Optional auto connect on mobile data +* Automatic service restart after reboot +* Service will stay running in background after app has been closed + +### Building + +_TODO_ + +### Credits + +This project is based on the "WG Tunnel" project made by Zane Schepke +https://github.com/zaneschepke/wgtunnel + +### License + +MIT diff --git a/nym-vpn/android/app/.gitignore b/nym-vpn/android/app/.gitignore new file mode 100644 index 0000000000..956c004dc0 --- /dev/null +++ b/nym-vpn/android/app/.gitignore @@ -0,0 +1,2 @@ +/build +/release \ No newline at end of file diff --git a/nym-vpn/android/app/build.gradle.kts b/nym-vpn/android/app/build.gradle.kts new file mode 100644 index 0000000000..bc158e58e9 --- /dev/null +++ b/nym-vpn/android/app/build.gradle.kts @@ -0,0 +1,159 @@ +val rExtra = rootProject.extra + +plugins { + id("com.android.application") + id("org.jetbrains.kotlin.android") + kotlin("kapt") + id("com.google.dagger.hilt.android") + id("org.jetbrains.kotlin.plugin.serialization") + id("io.objectbox") +} + +android { + namespace = "net.nymtech.nymconnect" + compileSdk = 34 + + val versionMajor = 1 + val versionMinor = 0 + val versionPatch = 0 + val versionBuild = 0 + + defaultConfig { + applicationId = "net.nymtech.nymconnect" + minSdk = 28 + targetSdk = 34 + versionCode = versionMajor * 10000 + versionMinor * 1000 + versionPatch * 100 + versionBuild + versionName = "${versionMajor}.${versionMinor}.${versionPatch}" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + vectorDrawables { + useSupportLibrary = true + } + } + + buildTypes { + release { + isDebuggable = false + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + kotlinOptions { + jvmTarget = "17" + } + buildFeatures { + compose = true + } + composeOptions { + kotlinCompilerExtensionVersion = "1.4.8" + } + packaging { + resources { + excludes += "/META-INF/{AL2.0,LGPL2.1}" + } + } + + /* flavorDimensions += "abi" + productFlavors { + create("universal") { + dimension = "abi" + ndk { + abiFilters += listOf("arm64-v8a", "armeabi-v7a", "x86_64", "x86") + } + } + create("arch64") { + dimension = "abi" + ndk { + abiFilters += listOf("arm64-v8a", "x86_64") + } + } + create("arm64") { + dimension = "abi" + ndk { + abiFilters += "arm64-v8a" + } + } + create("arm") { + dimension = "abi" + ndk { + abiFilters += "armeabi-v7a" + } + } + create("x86_64") { + dimension = "abi" + ndk { + abiFilters += "x86_64" + } + } + create("x86") { + dimension = "abi" + ndk { + abiFilters += "x86" + } + } + } */ +} + +dependencies { + implementation("androidx.core:core-ktx:1.10.1") + implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.1") + implementation("androidx.activity:activity-compose:1.7.2") + implementation(platform("androidx.compose:compose-bom:2023.03.00")) + implementation("androidx.compose.ui:ui") + implementation("androidx.compose.ui:ui-graphics") + implementation("androidx.compose.ui:ui-tooling-preview") + implementation("androidx.compose.material3:material3:1.1.1") + implementation("androidx.appcompat:appcompat:1.6.1") + + testImplementation("junit:junit:4.13.2") + androidTestImplementation("androidx.test.ext:junit:1.1.5") + androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") + androidTestImplementation(platform("androidx.compose:compose-bom:2023.03.00")) + androidTestImplementation("androidx.compose.ui:ui-test-junit4") + debugImplementation("androidx.compose.ui:ui-tooling") + debugImplementation("androidx.compose.ui:ui-test-manifest") + + //wireguard tunnel + implementation("com.wireguard.android:tunnel:1.0.20230706") + + //logging + implementation("com.jakewharton.timber:timber:5.0.1") + + // compose navigation + implementation("androidx.navigation:navigation-compose:2.7.1") + implementation("androidx.hilt:hilt-navigation-compose:1.0.0") + + // hilt + implementation("com.google.dagger:hilt-android:${rExtra.get("hiltVersion")}") + kapt("com.google.dagger:hilt-android-compiler:${rExtra.get("hiltVersion")}") + + //accompanist + implementation("com.google.accompanist:accompanist-systemuicontroller:${rExtra.get("accompanistVersion")}") + implementation("com.google.accompanist:accompanist-permissions:${rExtra.get("accompanistVersion")}") + implementation("com.google.accompanist:accompanist-flowlayout:${rExtra.get("accompanistVersion")}") + implementation("com.google.accompanist:accompanist-navigation-animation:${rExtra.get("accompanistVersion")}") + implementation("com.google.accompanist:accompanist-drawablepainter:${rExtra.get("accompanistVersion")}") + + //db + implementation("io.objectbox:objectbox-kotlin:${rExtra.get("objectBoxVersion")}") + + //lifecycle + implementation("androidx.lifecycle:lifecycle-runtime-compose:2.6.1") + + //icons + implementation("androidx.compose.material:material-icons-extended:1.5.0") + + + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1") +} + +kapt { + correctErrorTypes = true +} \ No newline at end of file diff --git a/nym-vpn/android/app/objectbox-models/default.json b/nym-vpn/android/app/objectbox-models/default.json new file mode 100644 index 0000000000..dd7a8ab78e --- /dev/null +++ b/nym-vpn/android/app/objectbox-models/default.json @@ -0,0 +1,99 @@ +{ + "_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.", + "_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.", + "_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.", + "entities": [ + { + "id": "1:2692736974585027589", + "lastPropertyId": "15:5057486545428188436", + "name": "TunnelConfig", + "properties": [ + { + "id": "1:1985347930017457084", + "name": "id", + "type": 6, + "flags": 1 + }, + { + "id": "12:2409068226744965585", + "name": "name", + "indexId": "1:4811206443952699137", + "type": 9, + "flags": 34848 + }, + { + "id": "13:8987443291286312275", + "name": "wgQuick", + "type": 9 + } + ], + "relations": [] + }, + { + "id": "2:8887605597748372702", + "lastPropertyId": "9:4468844863383145378", + "name": "Settings", + "properties": [ + { + "id": "1:7485739868216068651", + "name": "id", + "type": 6, + "flags": 1 + }, + { + "id": "2:5814013113141456749", + "name": "isAutoTunnelEnabled", + "type": 1 + }, + { + "id": "4:5645665441196906014", + "name": "trustedNetworkSSIDs", + "type": 30 + }, + { + "id": "5:4989886999117763881", + "name": "isTunnelOnMobileDataEnabled", + "type": 1 + }, + { + "id": "6:3370284381040192129", + "name": "defaultTunnel", + "type": 9 + }, + { + "id": "9:4468844863383145378", + "name": "isAlwaysOnVpnEnabled", + "type": 1 + } + ], + "relations": [] + } + ], + "lastEntityId": "2:8887605597748372702", + "lastIndexId": "1:4811206443952699137", + "lastRelationId": "0:0", + "lastSequenceId": "0:0", + "modelVersion": 5, + "modelVersionParserMinimum": 5, + "retiredEntityUids": [], + "retiredIndexUids": [], + "retiredPropertyUids": [ + 1763475292291320186, + 6483820955437198310, + 8323071516033820771, + 5904440563612311217, + 1408037976996390989, + 7737847485212546994, + 8215616901775229364, + 8021610768066328637, + 6174306582797008721, + 2175939938544485767, + 7555225587864607050, + 969146862000617878, + 5057486545428188436, + 2814640993034665120, + 4981008812459251156 + ], + "retiredRelationUids": [], + "version": 1 +} \ No newline at end of file diff --git a/nym-vpn/android/app/objectbox-models/default.json.bak b/nym-vpn/android/app/objectbox-models/default.json.bak new file mode 100644 index 0000000000..d4084866ef --- /dev/null +++ b/nym-vpn/android/app/objectbox-models/default.json.bak @@ -0,0 +1,94 @@ +{ + "_note1": "KEEP THIS FILE! Check it into a version control system (VCS) like git.", + "_note2": "ObjectBox manages crucial IDs for your object model. See docs for details.", + "_note3": "If you have VCS merge conflicts, you must resolve them according to ObjectBox docs.", + "entities": [ + { + "id": "1:2692736974585027589", + "lastPropertyId": "15:5057486545428188436", + "name": "TunnelConfig", + "properties": [ + { + "id": "1:1985347930017457084", + "name": "id", + "type": 6, + "flags": 1 + }, + { + "id": "12:2409068226744965585", + "name": "name", + "indexId": "1:4811206443952699137", + "type": 9, + "flags": 34848 + }, + { + "id": "13:8987443291286312275", + "name": "wgQuick", + "type": 9 + } + ], + "relations": [] + }, + { + "id": "2:8887605597748372702", + "lastPropertyId": "8:4981008812459251156", + "name": "Settings", + "properties": [ + { + "id": "1:7485739868216068651", + "name": "id", + "type": 6, + "flags": 1 + }, + { + "id": "2:5814013113141456749", + "name": "isAutoTunnelEnabled", + "type": 1 + }, + { + "id": "4:5645665441196906014", + "name": "trustedNetworkSSIDs", + "type": 30 + }, + { + "id": "5:4989886999117763881", + "name": "isTunnelOnMobileDataEnabled", + "type": 1 + }, + { + "id": "6:3370284381040192129", + "name": "defaultTunnel", + "type": 9 + } + ], + "relations": [] + } + ], + "lastEntityId": "2:8887605597748372702", + "lastIndexId": "1:4811206443952699137", + "lastRelationId": "0:0", + "lastSequenceId": "0:0", + "modelVersion": 5, + "modelVersionParserMinimum": 5, + "retiredEntityUids": [], + "retiredIndexUids": [], + "retiredPropertyUids": [ + 1763475292291320186, + 6483820955437198310, + 8323071516033820771, + 5904440563612311217, + 1408037976996390989, + 7737847485212546994, + 8215616901775229364, + 8021610768066328637, + 6174306582797008721, + 2175939938544485767, + 7555225587864607050, + 969146862000617878, + 5057486545428188436, + 2814640993034665120, + 4981008812459251156 + ], + "retiredRelationUids": [], + "version": 1 +} \ No newline at end of file diff --git a/nym-vpn/android/app/proguard-rules.pro b/nym-vpn/android/app/proguard-rules.pro new file mode 100644 index 0000000000..481bb43481 --- /dev/null +++ b/nym-vpn/android/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/nym-vpn/android/app/src/androidTest/java/com/zaneschepke/wireguardautotunnel/ExampleInstrumentedTest.kt b/nym-vpn/android/app/src/androidTest/java/com/zaneschepke/wireguardautotunnel/ExampleInstrumentedTest.kt new file mode 100644 index 0000000000..c006861187 --- /dev/null +++ b/nym-vpn/android/app/src/androidTest/java/com/zaneschepke/wireguardautotunnel/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package net.nymtech.nymconnect + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("net.nymtech.nymconnect", appContext.packageName) + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/AndroidManifest.xml b/nym-vpn/android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..2ff4f063bb --- /dev/null +++ b/nym-vpn/android/app/src/main/AndroidManifest.xml @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/ic_launcher-playstore.png b/nym-vpn/android/app/src/main/ic_launcher-playstore.png new file mode 100644 index 0000000000000000000000000000000000000000..e5d8e99564658add3373147cb1504f3eb1e9776f GIT binary patch literal 39338 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 UitnrlZu;iLF&ndYM?E6{2jO2F=>Px# literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/Constants.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/Constants.kt new file mode 100644 index 0000000000..c34ccaa493 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/Constants.kt @@ -0,0 +1,6 @@ +package net.nymtech.nymconnect + +object Constants { + const val VPN_CONNECTIVITY_CHECK_INTERVAL = 3000L; + const val VPN_STATISTIC_CHECK_INTERVAL = 10000L; +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt new file mode 100644 index 0000000000..f0d53e5162 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/WireGuardAutoTunnel.kt @@ -0,0 +1,27 @@ +package net.nymtech.nymconnect + +import android.app.Application +import android.content.Context +import android.content.pm.PackageManager +import net.nymtech.nymconnect.repository.Repository +import net.nymtech.nymconnect.service.tunnel.model.Settings +import dagger.hilt.android.HiltAndroidApp +import javax.inject.Inject + +@HiltAndroidApp +class WireGuardAutoTunnel : Application() { + + @Inject + lateinit var settingsRepo : Repository + + override fun onCreate() { + super.onCreate() + settingsRepo.init() + } + + companion object { + fun isRunningOnAndroidTv(context : Context) : Boolean { + return context.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK) + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/BoxModule.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/BoxModule.kt new file mode 100644 index 0000000000..032232369b --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/BoxModule.kt @@ -0,0 +1,40 @@ +package net.nymtech.nymconnect.module + +import android.content.Context +import net.nymtech.nymconnect.service.tunnel.model.MyObjectBox +import net.nymtech.nymconnect.service.tunnel.model.Settings +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import io.objectbox.Box +import io.objectbox.BoxStore +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +class BoxModule { + + @Provides + @Singleton + fun provideBoxStore(@ApplicationContext context : Context) : BoxStore { + return MyObjectBox.builder() + .androidContext(context.applicationContext) + .build() + } + + @Provides + @Singleton + fun provideBoxForSettings(store : BoxStore) : Box { + return store.boxFor(Settings::class.java) + } + + @Provides + @Singleton + fun provideBoxForTunnels(store : BoxStore) : Box { + return store.boxFor(TunnelConfig::class.java) + } + +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/RepositoryModule.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/RepositoryModule.kt new file mode 100644 index 0000000000..e402249cba --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/RepositoryModule.kt @@ -0,0 +1,25 @@ +package net.nymtech.nymconnect.module + +import net.nymtech.nymconnect.repository.Repository +import net.nymtech.nymconnect.repository.SettingsBox +import net.nymtech.nymconnect.repository.TunnelBox +import net.nymtech.nymconnect.service.tunnel.model.Settings +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +abstract class RepositoryModule { + + @Binds + @Singleton + abstract fun provideSettingsRepository(settingsBox: SettingsBox) : Repository + + @Binds + @Singleton + abstract fun provideTunnelRepository(tunnelBox: TunnelBox) : Repository +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/ServiceModule.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/ServiceModule.kt new file mode 100644 index 0000000000..fa043ec549 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/ServiceModule.kt @@ -0,0 +1,29 @@ +package net.nymtech.nymconnect.module + +import net.nymtech.nymconnect.service.network.MobileDataService +import net.nymtech.nymconnect.service.network.NetworkService +import net.nymtech.nymconnect.service.network.WifiService +import net.nymtech.nymconnect.service.notification.NotificationService +import net.nymtech.nymconnect.service.notification.WireGuardNotification +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.android.components.ServiceComponent +import dagger.hilt.android.scopes.ServiceScoped + +@Module +@InstallIn(ServiceComponent::class) +abstract class ServiceModule { + + @Binds + @ServiceScoped + abstract fun provideNotificationService(wireGuardNotification: WireGuardNotification) : NotificationService + + @Binds + @ServiceScoped + abstract fun provideWifiService(wifiService: WifiService) : NetworkService + + @Binds + @ServiceScoped + abstract fun provideMobileDataService(mobileDataService : MobileDataService) : NetworkService +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/TunnelModule.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/TunnelModule.kt new file mode 100644 index 0000000000..b5962a39d9 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/module/TunnelModule.kt @@ -0,0 +1,31 @@ +package net.nymtech.nymconnect.module + +import android.content.Context +import com.wireguard.android.backend.Backend +import com.wireguard.android.backend.GoBackend +import net.nymtech.nymconnect.service.tunnel.VpnService +import net.nymtech.nymconnect.service.tunnel.WireGuardTunnel +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.android.qualifiers.ApplicationContext +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +class TunnelModule { + + @Provides + @Singleton + fun provideBackend(@ApplicationContext context : Context) : Backend { + return GoBackend(context) + } + + @Provides + @Singleton + fun provideVpnService(backend: Backend) : VpnService { + return WireGuardTunnel(backend) + } + +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt new file mode 100644 index 0000000000..8fcf823c4f --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/BootReceiver.kt @@ -0,0 +1,39 @@ +package net.nymtech.nymconnect.receiver + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import net.nymtech.nymconnect.repository.Repository +import net.nymtech.nymconnect.service.foreground.ServiceManager +import net.nymtech.nymconnect.service.tunnel.model.Settings +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import javax.inject.Inject + +@AndroidEntryPoint +class BootReceiver : BroadcastReceiver() { + + @Inject + lateinit var settingsRepo : Repository + + override fun onReceive(context: Context, intent: Intent) { + if (intent.action == Intent.ACTION_BOOT_COMPLETED) { + CoroutineScope(Dispatchers.IO).launch { + try { + val settings = settingsRepo.getAll() + if (!settings.isNullOrEmpty()) { + val setting = settings.first() + if (setting.isAutoTunnelEnabled && setting.defaultTunnel != null) { + ServiceManager.startWatcherService(context, setting.defaultTunnel!!) + } + } + } finally { + cancel() + } + } + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/NotificationActionReceiver.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/NotificationActionReceiver.kt new file mode 100644 index 0000000000..97033a8f63 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/receiver/NotificationActionReceiver.kt @@ -0,0 +1,39 @@ +package net.nymtech.nymconnect.receiver + +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import net.nymtech.nymconnect.repository.Repository +import net.nymtech.nymconnect.service.foreground.ServiceManager +import net.nymtech.nymconnect.service.tunnel.model.Settings +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.cancel +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import javax.inject.Inject + +@AndroidEntryPoint +class NotificationActionReceiver : BroadcastReceiver() { + + @Inject + lateinit var settingsRepo : Repository + override fun onReceive(context: Context, intent: Intent?) { + CoroutineScope(Dispatchers.IO).launch { + try { + val settings = settingsRepo.getAll() + if (!settings.isNullOrEmpty()) { + val setting = settings.first() + if (setting.defaultTunnel != null) { + ServiceManager.stopVpnService(context) + delay(1000) + ServiceManager.startVpnService(context, setting.defaultTunnel.toString()) + } + } + } finally { + cancel() + } + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/Repository.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/Repository.kt new file mode 100644 index 0000000000..187957132c --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/Repository.kt @@ -0,0 +1,16 @@ +package net.nymtech.nymconnect.repository + +import kotlinx.coroutines.flow.Flow + +interface Repository { + suspend fun save(t : T) + suspend fun saveAll(t : List) + suspend fun getById(id : Long) : T? + suspend fun getAll() : List? + suspend fun delete(t : T) : Boolean? + suspend fun count() : Long? + + val itemFlow : Flow> + + fun init() +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/SettingsBox.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/SettingsBox.kt new file mode 100644 index 0000000000..f56247463c --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/SettingsBox.kt @@ -0,0 +1,63 @@ +package net.nymtech.nymconnect.repository + +import net.nymtech.nymconnect.service.tunnel.model.Settings +import io.objectbox.Box +import io.objectbox.BoxStore +import io.objectbox.kotlin.awaitCallInTx +import io.objectbox.kotlin.toFlow +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.launch +import javax.inject.Inject + + +class SettingsBox @Inject constructor(private val box : Box, private val boxStore : BoxStore) : Repository { + + @OptIn(ExperimentalCoroutinesApi::class) + override val itemFlow = box.query().build().subscribe().toFlow() + + override fun init() { + CoroutineScope(Dispatchers.IO).launch { + if(getAll().isNullOrEmpty()) { + save(Settings()) + } + } + } + + override suspend fun save(t : Settings) { + boxStore.awaitCallInTx { + box.put(t) + } + } + + override suspend fun saveAll(t : List) { + boxStore.awaitCallInTx { + box.put(t) + } + } + + override suspend fun getById(id: Long): Settings? { + return boxStore.awaitCallInTx { + box[id] + } + } + + override suspend fun getAll(): List? { + return boxStore.awaitCallInTx { + box.all + } + } + + override suspend fun delete(t : Settings): Boolean? { + return boxStore.awaitCallInTx { + box.remove(t) + } + } + + override suspend fun count() : Long? { + return boxStore.awaitCallInTx { + box.count() + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/TunnelBox.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/TunnelBox.kt new file mode 100644 index 0000000000..c57621d53c --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/repository/TunnelBox.kt @@ -0,0 +1,57 @@ +package net.nymtech.nymconnect.repository + +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig +import io.objectbox.Box +import io.objectbox.BoxStore +import io.objectbox.kotlin.awaitCallInTx +import io.objectbox.kotlin.toFlow +import kotlinx.coroutines.ExperimentalCoroutinesApi +import timber.log.Timber +import javax.inject.Inject + +class TunnelBox @Inject constructor(private val box : Box,private val boxStore : BoxStore) : Repository { + + @OptIn(ExperimentalCoroutinesApi::class) + override val itemFlow = box.query().build().subscribe().toFlow() + override fun init() { + + } + + override suspend fun save(t : TunnelConfig) { + Timber.d("Saving tunnel config") + boxStore.awaitCallInTx { + box.put(t) + } + + } + + override suspend fun saveAll(t : List) { + boxStore.awaitCallInTx { + box.put(t) + } + } + + override suspend fun getById(id: Long): TunnelConfig? { + return boxStore.awaitCallInTx { + box[id] + } + } + + override suspend fun getAll(): List? { + return boxStore.awaitCallInTx { + box.all + } + } + + override suspend fun delete(t : TunnelConfig): Boolean? { + return boxStore.awaitCallInTx { + box.remove(t) + } + } + + override suspend fun count() : Long? { + return boxStore.awaitCallInTx { + box.count() + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/Action.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/Action.kt new file mode 100644 index 0000000000..ba4f930b12 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/Action.kt @@ -0,0 +1,6 @@ +package net.nymtech.nymconnect.service.foreground + +enum class Action { + START, + STOP +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ForegroundService.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ForegroundService.kt new file mode 100644 index 0000000000..9aaf0b93d8 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ForegroundService.kt @@ -0,0 +1,64 @@ +package net.nymtech.nymconnect.service.foreground + +import android.app.Service +import android.content.Intent +import android.os.Bundle +import android.os.IBinder +import timber.log.Timber + + +open class ForegroundService : Service() { + + private var isServiceStarted = false + + override fun onBind(intent: Intent): IBinder? { + // We don't provide binding, so return null + return null + } + + override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { + Timber.d("onStartCommand executed with startId: $startId") + if (intent != null) { + val action = intent.action + Timber.d("using an intent with action $action") + when (action) { + Action.START.name -> startService(intent.extras) + Action.STOP.name -> stopService(intent.extras) + "android.net.VpnService" -> { + Timber.d("Always-on VPN starting service") + startService(intent.extras) + } + else -> Timber.d("This should never happen. No action in the received intent") + } + } else { + Timber.d( + "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?) { + Timber.d("Stopping ${this.javaClass.simpleName}") + try { + stopForeground(STOP_FOREGROUND_REMOVE) + stopSelf() + } catch (e: Exception) { + Timber.d("Service stopped without being started: ${e.message}") + } + isServiceStarted = false + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceManager.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceManager.kt new file mode 100644 index 0000000000..c00a796453 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceManager.kt @@ -0,0 +1,90 @@ +package net.nymtech.nymconnect.service.foreground + +import android.app.ActivityManager +import android.app.Application +import android.app.Service +import android.content.Context +import android.content.Context.ACTIVITY_SERVICE +import android.content.Intent +import net.nymtech.nymconnect.R +import timber.log.Timber + +object ServiceManager { + @Suppress("DEPRECATION") + private // Deprecated for third party Services. + fun Context.isServiceRunning(service: Class) = + (getSystemService(ACTIVITY_SERVICE) as ActivityManager) + .getRunningServices(Integer.MAX_VALUE) + .any { it.service.className == service.name } + + fun getServiceState(context: Context, cls : Class): ServiceState { + val isServiceRunning = context.isServiceRunning(cls) + return if(isServiceRunning) ServiceState.STARTED else ServiceState.STOPPED + } + + private fun actionOnService(action: Action, context: Context, cls : Class, extras : Map? = null) { + if (getServiceState(context, cls) == ServiceState.STOPPED && action == Action.STOP) return + if (getServiceState(context, cls) == ServiceState.STARTED && action == Action.START) return + val intent = Intent(context, cls).also { + it.action = action.name + extras?.forEach {(k, v) -> + it.putExtra(k, v) + } + } + intent.component?.javaClass + try { + when(action) { + Action.START -> { + try { + context.startForegroundService(intent) + } catch (e : Exception) { + Timber.e("Unable to start service foreground ${e.message}") + context.startService(intent) + } + } + Action.STOP -> context.startService(intent) + } + } catch (e : Exception) { + Timber.tag("ServiceManager").e(e) + } + } + + fun startVpnService(context : Context, tunnelConfig : String) { + actionOnService( + Action.START, + context, + WireGuardTunnelService::class.java, + mapOf(context.getString(R.string.tunnel_extras_key) to tunnelConfig)) + } + fun stopVpnService(context : Context) { + actionOnService( + Action.STOP, + context, + WireGuardTunnelService::class.java + ) + } + + fun startWatcherService(context : Context, tunnelConfig : String) { + actionOnService( + Action.START, context, + WireGuardConnectivityWatcherService::class.java, mapOf(context. + getString(R.string.tunnel_extras_key) to + tunnelConfig)) + } + + fun stopWatcherService(context : Context) { + actionOnService( + Action.STOP, context, + WireGuardConnectivityWatcherService::class.java) + } + + fun toggleWatcherService(context: Context, tunnelConfig : String) { + when(getServiceState( + context, + WireGuardConnectivityWatcherService::class.java, + )) { + ServiceState.STARTED -> stopWatcherService(context) + ServiceState.STOPPED -> startWatcherService(context, tunnelConfig) + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceState.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceState.kt new file mode 100644 index 0000000000..9c26fa0795 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/ServiceState.kt @@ -0,0 +1,6 @@ +package net.nymtech.nymconnect.service.foreground + +enum class ServiceState { + STARTED, + STOPPED, +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt new file mode 100644 index 0000000000..fcfa811ea2 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardConnectivityWatcherService.kt @@ -0,0 +1,210 @@ +package net.nymtech.nymconnect.service.foreground + +import android.app.AlarmManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.os.Bundle +import android.os.PowerManager +import android.os.SystemClock +import com.wireguard.android.backend.Tunnel +import net.nymtech.nymconnect.Constants +import net.nymtech.nymconnect.R +import net.nymtech.nymconnect.repository.Repository +import net.nymtech.nymconnect.service.network.MobileDataService +import net.nymtech.nymconnect.service.network.NetworkService +import net.nymtech.nymconnect.service.network.NetworkStatus +import net.nymtech.nymconnect.service.network.WifiService +import net.nymtech.nymconnect.service.notification.NotificationService +import net.nymtech.nymconnect.service.tunnel.VpnService +import net.nymtech.nymconnect.service.tunnel.model.Settings +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import timber.log.Timber +import javax.inject.Inject + +@AndroidEntryPoint +class WireGuardConnectivityWatcherService : ForegroundService() { + + private val foregroundId = 122; + + @Inject + lateinit var wifiService : NetworkService + + @Inject + lateinit var mobileDataService : NetworkService + + @Inject + lateinit var settingsRepo: Repository + + @Inject + lateinit var notificationService : NotificationService + + @Inject + lateinit var vpnService : VpnService + + private var isWifiConnected = false; + private var isMobileDataConnected = false; + private var currentNetworkSSID = ""; + + private lateinit var watcherJob : Job; + private lateinit var setting : Settings + private lateinit var tunnelConfig: String + + private var wakeLock: PowerManager.WakeLock? = null + private val tag = this.javaClass.name; + + + override fun startService(extras: Bundle?) { + super.startService(extras) + val tunnelId = extras?.getString(getString(R.string.tunnel_extras_key)) + if (tunnelId != null) { + this.tunnelConfig = tunnelId + } + // we need this lock so our service gets not affected by Doze Mode + initWakeLock() + cancelWatcherJob() + launchWatcherNotification() + if(this::tunnelConfig.isInitialized) { + startWatcherJob() + } else { + stopService(extras) + } + } + + override fun stopService(extras: Bundle?) { + super.stopService(extras) + wakeLock?.let { + if (it.isHeld) { + it.release() + } + } + cancelWatcherJob() + stopSelf() + } + + private fun launchWatcherNotification() { + val notification = notificationService.createNotification( + channelId = getString(R.string.watcher_channel_id), + channelName = getString(R.string.watcher_channel_name), + description = getString(R.string.watcher_notification_text)) + super.startForeground(foregroundId, notification) + } + + //try to start task again if killed + override fun onTaskRemoved(rootIntent: Intent) { + Timber.d("Task Removed called") + val restartServiceIntent = Intent(rootIntent) + val restartServicePendingIntent: PendingIntent = PendingIntent.getService(this, 1, restartServiceIntent, + PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_IMMUTABLE); + applicationContext.getSystemService(Context.ALARM_SERVICE); + val alarmService: AlarmManager = applicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager; + alarmService.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 1000, restartServicePendingIntent); + } + + private fun initWakeLock() { + wakeLock = + (getSystemService(Context.POWER_SERVICE) as PowerManager).run { + newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "$tag::lock").apply { + acquire() + } + } + } + + private fun cancelWatcherJob() { + if(this::watcherJob.isInitialized) { + watcherJob.cancel() + } + } + + private fun startWatcherJob() { + watcherJob = CoroutineScope(Dispatchers.IO).launch { + val settings = settingsRepo.getAll(); + if(!settings.isNullOrEmpty()) { + setting = settings[0] + } + launch { + watchForWifiConnectivityChanges() + } + if(setting.isTunnelOnMobileDataEnabled) { + launch { + watchForMobileDataConnectivityChanges() + } + } + launch { + manageVpn() + } + } + } + + private suspend fun watchForMobileDataConnectivityChanges() { + mobileDataService.networkStatus.collect { + when(it) { + is NetworkStatus.Available -> { + Timber.d("Gained Mobile data connection") + isMobileDataConnected = true + } + is NetworkStatus.CapabilitiesChanged -> { + isMobileDataConnected = true + Timber.d("Mobile data capabilities changed") + } + is NetworkStatus.Unavailable -> { + isMobileDataConnected = false + Timber.d("Lost mobile data connection") + } + + else -> {} + } + } + } + + private suspend fun watchForWifiConnectivityChanges() { + wifiService.networkStatus.collect { + when (it) { + is NetworkStatus.Available -> { + Timber.d("Gained Wi-Fi connection") + isWifiConnected = true + } + is NetworkStatus.CapabilitiesChanged -> { + Timber.d("Wifi capabilities changed") + isWifiConnected = true + currentNetworkSSID = wifiService.getNetworkName(it.networkCapabilities) ?: ""; + } + is NetworkStatus.Unavailable -> { + isWifiConnected = false + Timber.d("Lost Wi-Fi connection") + } + + else -> {} + } + } + } + + private suspend fun manageVpn() { + while(watcherJob.isActive) { + if(setting.isTunnelOnMobileDataEnabled && + !isWifiConnected && + isMobileDataConnected + && vpnService.getState() == Tunnel.State.DOWN) { + ServiceManager.startVpnService(this, tunnelConfig) + } else if(!setting.isTunnelOnMobileDataEnabled && + !isWifiConnected && + vpnService.getState() == Tunnel.State.UP) { + ServiceManager.stopVpnService(this) + } else if(isWifiConnected && + !setting.trustedNetworkSSIDs.contains(currentNetworkSSID) && + (vpnService.getState() != Tunnel.State.UP)) { + ServiceManager.startVpnService(this, tunnelConfig) + } else if((isWifiConnected && + setting.trustedNetworkSSIDs.contains(currentNetworkSSID)) && + (vpnService.getState() == Tunnel.State.UP)) { + ServiceManager.stopVpnService(this) + } + delay(Constants.VPN_CONNECTIVITY_CHECK_INTERVAL) + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt new file mode 100644 index 0000000000..776928e649 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/foreground/WireGuardTunnelService.kt @@ -0,0 +1,154 @@ +package net.nymtech.nymconnect.service.foreground + +import android.app.PendingIntent +import android.content.Intent +import android.os.Bundle +import net.nymtech.nymconnect.R +import net.nymtech.nymconnect.receiver.NotificationActionReceiver +import net.nymtech.nymconnect.repository.Repository +import net.nymtech.nymconnect.service.notification.NotificationService +import net.nymtech.nymconnect.service.tunnel.HandshakeStatus +import net.nymtech.nymconnect.service.tunnel.VpnService +import net.nymtech.nymconnect.service.tunnel.model.Settings +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.launch +import timber.log.Timber +import javax.inject.Inject + +@AndroidEntryPoint +class WireGuardTunnelService : ForegroundService() { + + private val foregroundId = 123; + + @Inject + lateinit var vpnService : VpnService + + @Inject + lateinit var settingsRepo: Repository + + @Inject + lateinit var notificationService : NotificationService + + private lateinit var job : Job + + private var tunnelName : String = "" + + override fun startService(extras : Bundle?) { + super.startService(extras) + val tunnelConfigString = extras?.getString(getString(R.string.tunnel_extras_key)) + cancelJob() + job = CoroutineScope(Dispatchers.IO).launch { + if(tunnelConfigString != null) { + try { + val tunnelConfig = TunnelConfig.from(tunnelConfigString) + tunnelName = tunnelConfig.name + vpnService.startTunnel(tunnelConfig) + launchVpnStartingNotification() + } catch (e : Exception) { + Timber.e("Problem starting tunnel: ${e.message}") + stopService(extras) + } + } else { + Timber.d("Tunnel config null, starting default tunnel") + val settings = settingsRepo.getAll(); + if(!settings.isNullOrEmpty()) { + val setting = settings[0] + if(setting.defaultTunnel != null && setting.isAlwaysOnVpnEnabled) { + val tunnelConfig = TunnelConfig.from(setting.defaultTunnel!!) + tunnelName = tunnelConfig.name + vpnService.startTunnel(tunnelConfig) + launchVpnStartingNotification() + } + } + } + } + CoroutineScope(job).launch { + var didShowConnected = false + var didShowFailedHandshakeNotification = false + vpnService.handshakeStatus.collect { + when(it) { + HandshakeStatus.NOT_STARTED -> { + } + HandshakeStatus.NEVER_CONNECTED -> { + if(!didShowFailedHandshakeNotification) { + launchVpnConnectionFailedNotification(getString(R.string.initial_connection_failure_message)) + didShowFailedHandshakeNotification = true + didShowConnected = false + } + } + HandshakeStatus.HEALTHY -> { + if(!didShowConnected) { + launchVpnConnectedNotification() + didShowConnected = true + } + } + HandshakeStatus.UNHEALTHY -> { + if(!didShowFailedHandshakeNotification) { + launchVpnConnectionFailedNotification(getString(R.string.lost_connection_failure_message)) + didShowFailedHandshakeNotification = true + didShowConnected = false + } + } + } + } + } + } + + override fun stopService(extras : Bundle?) { + super.stopService(extras) + CoroutineScope(Dispatchers.IO).launch() { + vpnService.stopTunnel() + } + cancelJob() + stopSelf() + } + + private fun launchVpnConnectedNotification() { + val notification = notificationService.createNotification( + channelId = getString(R.string.vpn_channel_id), + channelName = getString(R.string.vpn_channel_name), + title = getString(R.string.tunnel_start_title), + onGoing = false, + showTimestamp = true, + description = "${getString(R.string.tunnel_start_text)} $tunnelName" + ) + super.startForeground(foregroundId, notification) + } + + private fun launchVpnStartingNotification() { + val notification = notificationService.createNotification( + channelId = getString(R.string.vpn_channel_id), + channelName = getString(R.string.vpn_channel_name), + title = getString(R.string.vpn_starting), + onGoing = false, + showTimestamp = true, + description = getString(R.string.attempt_connection) + ) + super.startForeground(foregroundId, notification) + } + + private fun launchVpnConnectionFailedNotification(message : String) { + val notification = notificationService.createNotification( + channelId = getString(R.string.vpn_channel_id), + channelName = getString(R.string.vpn_channel_name), + action = PendingIntent.getBroadcast(this,0,Intent(this, NotificationActionReceiver::class.java),PendingIntent.FLAG_IMMUTABLE), + actionText = getString(R.string.restart), + title = getString(R.string.vpn_connection_failed), + onGoing = false, + showTimestamp = true, + description = message + ) + super.startForeground(foregroundId, notification) + } + + + private fun cancelJob() { + if(this::job.isInitialized) { + job.cancel() + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/BaseNetworkService.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/BaseNetworkService.kt new file mode 100644 index 0000000000..9574d659ef --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/BaseNetworkService.kt @@ -0,0 +1,117 @@ +package net.nymtech.nymconnect.service.network + +import android.content.Context +import android.net.ConnectivityManager +import android.net.Network +import android.net.NetworkCapabilities +import android.net.NetworkRequest +import android.net.wifi.SupplicantState +import android.net.wifi.WifiInfo +import android.net.wifi.WifiManager +import android.os.Build +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.map + + +abstract class BaseNetworkService>(val context: Context, networkCapability : Int) : NetworkService { + private val connectivityManager = + context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager + + private val wifiManager = + context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager + + override val networkStatus = callbackFlow { + val networkStatusCallback = when (Build.VERSION.SDK_INT) { + in Build.VERSION_CODES.S..Int.MAX_VALUE -> { + object : ConnectivityManager.NetworkCallback( + FLAG_INCLUDE_LOCATION_INFO + ) { + override fun onAvailable(network: Network) { + trySend(NetworkStatus.Available(network)) + } + + override fun onLost(network: Network) { + trySend(NetworkStatus.Unavailable(network)) + } + + override fun onCapabilitiesChanged( + network: Network, + networkCapabilities: NetworkCapabilities + ) { + trySend(NetworkStatus.CapabilitiesChanged(network, networkCapabilities)) + } + } + } + + else -> { + object : ConnectivityManager.NetworkCallback() { + + override fun onAvailable(network: Network) { + trySend(NetworkStatus.Available(network)) + } + + override fun onLost(network: Network) { + trySend(NetworkStatus.Unavailable(network)) + } + + override fun onCapabilitiesChanged( + network: Network, + networkCapabilities: NetworkCapabilities + ) { + trySend(NetworkStatus.CapabilitiesChanged(network, networkCapabilities)) + } + } + } + } + val request = NetworkRequest.Builder() + .addTransportType(networkCapability) + .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) + .addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) + .build() + connectivityManager.registerNetworkCallback(request, networkStatusCallback) + + awaitClose { + connectivityManager.unregisterNetworkCallback(networkStatusCallback) + } + } + + + override fun getNetworkName(networkCapabilities: NetworkCapabilities): String? { + var ssid: String? = getWifiNameFromCapabilities(networkCapabilities) + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.R) { + val info = wifiManager.connectionInfo + if (info.supplicantState === SupplicantState.COMPLETED) { + ssid = info.ssid + } + } + return ssid?.trim('"') + } + + + companion object { + private fun getWifiNameFromCapabilities(networkCapabilities: NetworkCapabilities): String? { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + val info: WifiInfo + if (networkCapabilities.transportInfo is WifiInfo) { + info = networkCapabilities.transportInfo as WifiInfo + return info.ssid + } + } + return null + } + } +} + +inline fun Flow.map( + crossinline onUnavailable: suspend (network : Network) -> Result, + crossinline onAvailable: suspend (network : Network) -> Result, + crossinline onCapabilitiesChanged: suspend (network : Network, networkCapabilities : NetworkCapabilities) -> Result, +): Flow = map { status -> + when (status) { + is NetworkStatus.Unavailable -> onUnavailable(status.network) + is NetworkStatus.Available -> onAvailable(status.network) + is NetworkStatus.CapabilitiesChanged -> onCapabilitiesChanged(status.network, status.networkCapabilities) + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/MobileDataService.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/MobileDataService.kt new file mode 100644 index 0000000000..a067af06cf --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/MobileDataService.kt @@ -0,0 +1,10 @@ +package net.nymtech.nymconnect.service.network + +import android.content.Context +import android.net.NetworkCapabilities +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject + +class MobileDataService @Inject constructor(@ApplicationContext context: Context) : + BaseNetworkService(context, NetworkCapabilities.TRANSPORT_CELLULAR) { +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/NetworkService.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/NetworkService.kt new file mode 100644 index 0000000000..6c274dab03 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/NetworkService.kt @@ -0,0 +1,10 @@ +package net.nymtech.nymconnect.service.network + +import android.net.NetworkCapabilities +import kotlinx.coroutines.flow.Flow + +interface NetworkService { + fun getNetworkName(networkCapabilities: NetworkCapabilities) : String? + val networkStatus : Flow + +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/NetworkStatus.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/NetworkStatus.kt new file mode 100644 index 0000000000..5446ce52a6 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/NetworkStatus.kt @@ -0,0 +1,10 @@ +package net.nymtech.nymconnect.service.network + +import android.net.Network +import android.net.NetworkCapabilities + +sealed class NetworkStatus { + class Available(val network : Network) : NetworkStatus() + class Unavailable(val network : Network) : NetworkStatus() + class CapabilitiesChanged(val network : Network, val networkCapabilities : NetworkCapabilities) : NetworkStatus() +} diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/WifiService.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/WifiService.kt new file mode 100644 index 0000000000..a01ebba746 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/network/WifiService.kt @@ -0,0 +1,10 @@ +package net.nymtech.nymconnect.service.network + +import android.content.Context +import android.net.NetworkCapabilities +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject + +class WifiService @Inject constructor(@ApplicationContext context: Context) : + BaseNetworkService(context, NetworkCapabilities.TRANSPORT_WIFI) { +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/notification/NotificationService.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/notification/NotificationService.kt new file mode 100644 index 0000000000..4071e64202 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/notification/NotificationService.kt @@ -0,0 +1,21 @@ +package net.nymtech.nymconnect.service.notification + +import android.app.Notification +import android.app.NotificationManager +import android.app.PendingIntent + +interface NotificationService { + fun createNotification( + channelId: String, + channelName: String, + title: String = "", + action: PendingIntent? = null, + actionText: String? = null, + description: String, + showTimestamp : Boolean = false, + importance: Int = NotificationManager.IMPORTANCE_HIGH, + vibration: Boolean = true, + onGoing: Boolean = true, + lights: Boolean = true + ): Notification +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/notification/WireGuardNotification.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/notification/WireGuardNotification.kt new file mode 100644 index 0000000000..4e4cdb3e1b --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/notification/WireGuardNotification.kt @@ -0,0 +1,77 @@ +package net.nymtech.nymconnect.service.notification + +import android.app.Notification +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent +import android.content.Context +import android.content.Intent +import android.graphics.Color +import net.nymtech.nymconnect.R +import net.nymtech.nymconnect.ui.MainActivity +import dagger.hilt.android.qualifiers.ApplicationContext +import javax.inject.Inject + +class WireGuardNotification @Inject constructor(@ApplicationContext private val context: Context) : NotificationService { + + private val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager; + + override fun createNotification( + channelId: String, + channelName: String, + title: String, + action: PendingIntent?, + actionText: String?, + description: String, + showTimestamp: Boolean, + importance: Int, + vibration: Boolean, + onGoing: Boolean, + lights: Boolean + ): Notification { + val channel = NotificationChannel( + channelId, + channelName, + importance + ).let { + it.description = title + it.enableLights(lights) + it.lightColor = Color.RED + it.enableVibration(vibration) + it.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400) + it + } + notificationManager.createNotificationChannel(channel) + val pendingIntent: PendingIntent = + Intent(context, MainActivity::class.java).let { notificationIntent -> + PendingIntent.getActivity( + context, + 0, + notificationIntent, + PendingIntent.FLAG_IMMUTABLE + ) + } + + val builder: Notification.Builder = + Notification.Builder( + context, + channelId + ) + return builder.let { + if(action != null && actionText != null) { + //TODO find a not deprecated way to do this + it.addAction( + Notification.Action.Builder(0, actionText, action) + .build()) + it.setAutoCancel(true) + } + it.setContentTitle(title) + .setContentText(description) + .setContentIntent(pendingIntent) + .setOngoing(onGoing) + .setShowWhen(showTimestamp) + .setSmallIcon(R.mipmap.ic_launcher_foreground) + .build() + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsActivity.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsActivity.kt new file mode 100644 index 0000000000..c88825e71e --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsActivity.kt @@ -0,0 +1,28 @@ +package net.nymtech.nymconnect.service.shortcut + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import net.nymtech.nymconnect.R +import net.nymtech.nymconnect.service.foreground.Action +import net.nymtech.nymconnect.service.foreground.ServiceManager +import net.nymtech.nymconnect.service.foreground.WireGuardTunnelService +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class ShortcutsActivity : AppCompatActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + if(intent.getStringExtra(ShortcutsManager.CLASS_NAME_EXTRA_KEY) + .equals(WireGuardTunnelService::class.java.name)) { + intent.getStringExtra(getString(R.string.tunnel_extras_key))?.let { + ServiceManager.toggleWatcherService(this, it) + } + when(intent.action){ + Action.STOP.name -> ServiceManager.stopVpnService(this) + Action.START.name -> intent.getStringExtra(getString(R.string.tunnel_extras_key)) + ?.let { ServiceManager.startVpnService(this, it) } + } + } + finish() + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsManager.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsManager.kt new file mode 100644 index 0000000000..13df427ebd --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/shortcut/ShortcutsManager.kt @@ -0,0 +1,73 @@ +package net.nymtech.nymconnect.service.shortcut + +import android.content.Context +import android.content.Intent +import androidx.core.content.pm.ShortcutInfoCompat +import androidx.core.content.pm.ShortcutManagerCompat +import androidx.core.graphics.drawable.IconCompat +import net.nymtech.nymconnect.R +import net.nymtech.nymconnect.service.foreground.Action +import net.nymtech.nymconnect.service.foreground.WireGuardTunnelService +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig + +object ShortcutsManager { + + private const val SHORT_LABEL_MAX_SIZE = 10; + private const val LONG_LABEL_MAX_SIZE = 25; + private const val APPEND_ON = " On"; + private const val APPEND_OFF = " Off" + const val CLASS_NAME_EXTRA_KEY = "className" + + private fun createAndPushShortcut(context : Context, intent : Intent, id : String, shortLabel : String, + longLabel : String, drawable : Int ) { + val shortcut = ShortcutInfoCompat.Builder(context, id) + .setShortLabel(shortLabel) + .setLongLabel(longLabel) + .setIcon(IconCompat.createWithResource(context, drawable)) + .setIntent(intent) + .build() + ShortcutManagerCompat.pushDynamicShortcut(context, shortcut) + } + + fun createTunnelShortcuts(context : Context, tunnelConfig : TunnelConfig) { + createAndPushShortcut(context, + createTunnelOnIntent(context, mapOf(context.getString(R.string.tunnel_extras_key) to tunnelConfig.toString())), + tunnelConfig.id.toString() + APPEND_ON, + tunnelConfig.name.take((SHORT_LABEL_MAX_SIZE - APPEND_ON.length)) + APPEND_ON, + tunnelConfig.name.take((LONG_LABEL_MAX_SIZE - APPEND_ON.length)) + APPEND_ON, + R.drawable.vpn_on + ) + createAndPushShortcut(context, + createTunnelOffIntent(context, mapOf(context.getString(R.string.tunnel_extras_key) to tunnelConfig.toString())), + tunnelConfig.id.toString() + APPEND_OFF, + tunnelConfig.name.take((SHORT_LABEL_MAX_SIZE - APPEND_OFF.length)) + APPEND_OFF, + tunnelConfig.name.take((LONG_LABEL_MAX_SIZE - APPEND_OFF.length)) + APPEND_OFF, + R.drawable.vpn_off + ) + } + + fun removeTunnelShortcuts(context : Context, tunnelConfig : TunnelConfig) { + ShortcutManagerCompat.removeDynamicShortcuts(context, listOf(tunnelConfig.id.toString() + APPEND_ON, + tunnelConfig.id.toString() + APPEND_OFF )) + } + + private fun createTunnelOnIntent(context: Context, extras : Map) : Intent { + return Intent(context, ShortcutsActivity::class.java).also { + it.action = Action.START.name + it.putExtra(CLASS_NAME_EXTRA_KEY, WireGuardTunnelService::class.java.name) + extras.forEach {(k, v) -> + it.putExtra(k, v) + } + } + } + + private fun createTunnelOffIntent(context : Context, extras : Map) : Intent { + return Intent(context, ShortcutsActivity::class.java).also { + it.action = Action.STOP.name + it.putExtra(CLASS_NAME_EXTRA_KEY, WireGuardTunnelService::class.java.name) + extras.forEach {(k, v) -> + it.putExtra(k, v) + } + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt new file mode 100644 index 0000000000..38c774c963 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tile/TunnelControlTile.kt @@ -0,0 +1,142 @@ +package net.nymtech.nymconnect.service.tile + +import android.os.Build +import android.service.quicksettings.Tile +import android.service.quicksettings.TileService +import com.wireguard.android.backend.Tunnel +import net.nymtech.nymconnect.R +import net.nymtech.nymconnect.repository.Repository +import net.nymtech.nymconnect.service.foreground.ServiceManager +import net.nymtech.nymconnect.service.tunnel.VpnService +import net.nymtech.nymconnect.service.tunnel.model.Settings +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig +import dagger.hilt.android.AndroidEntryPoint +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.cancel +import kotlinx.coroutines.launch +import timber.log.Timber +import javax.inject.Inject + +@AndroidEntryPoint +class TunnelControlTile : TileService() { + + @Inject + lateinit var settingsRepo : Repository + + @Inject + lateinit var configRepo : Repository + + @Inject + lateinit var vpnService : VpnService + + private val scope = CoroutineScope(Dispatchers.Main); + + private lateinit var job : Job + + override fun onStartListening() { + job = scope.launch { + updateTileState() + } + super.onStartListening() + } + + override fun onTileAdded() { + super.onTileAdded() + qsTile.contentDescription = this.resources.getString(R.string.toggle_vpn) + scope.launch { + updateTileState(); + } + } + + override fun onTileRemoved() { + super.onTileRemoved() + cancelJob() + } + + override fun onClick() { + super.onClick() + unlockAndRun { + scope.launch { + try { + val tunnel = determineTileTunnel(); + if(tunnel != null) { + attemptWatcherServiceToggle(tunnel.toString()) + if(vpnService.getState() == Tunnel.State.UP) { + ServiceManager.stopVpnService(this@TunnelControlTile) + } else { + ServiceManager.startVpnService(this@TunnelControlTile, tunnel.toString()) + } + } + } catch (e : Exception) { + Timber.e(e.message) + } finally { + cancel() + } + } + } + } + + private suspend fun determineTileTunnel() : TunnelConfig? { + var tunnelConfig : TunnelConfig? = null; + val settings = settingsRepo.getAll() + if (!settings.isNullOrEmpty()) { + val setting = settings.first() + tunnelConfig = if (setting.defaultTunnel != null) { + TunnelConfig.from(setting.defaultTunnel!!); + } else { + val config = configRepo.getAll()?.first(); + config; + } + } + return tunnelConfig; + } + + + private fun attemptWatcherServiceToggle(tunnelConfig : String) { + scope.launch { + val settings = settingsRepo.getAll() + if (!settings.isNullOrEmpty()) { + val setting = settings.first() + if(setting.isAutoTunnelEnabled) { + ServiceManager.toggleWatcherService(this@TunnelControlTile, tunnelConfig) + } + } + } + } + + private suspend fun updateTileState() { + vpnService.state.collect { + when(it) { + Tunnel.State.UP -> { + qsTile.state = Tile.STATE_ACTIVE + } + Tunnel.State.DOWN -> { + qsTile.state = Tile.STATE_INACTIVE; + } + else -> { + qsTile.state = Tile.STATE_UNAVAILABLE + } + } + val config = determineTileTunnel(); + setTileDescription(config?.name ?: this.resources.getString(R.string.no_tunnel_available)) + qsTile.updateTile() + } + } + + private fun setTileDescription(description : String) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + qsTile.subtitle = description + } + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + qsTile.stateDescription = description; + } + } + + private fun cancelJob() { + if(this::job.isInitialized) { + job.cancel(); + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/HandshakeStatus.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/HandshakeStatus.kt new file mode 100644 index 0000000000..1d2fa54ea7 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/HandshakeStatus.kt @@ -0,0 +1,14 @@ +package net.nymtech.nymconnect.service.tunnel + +enum class HandshakeStatus { + HEALTHY, + UNHEALTHY, + NEVER_CONNECTED, + NOT_STARTED; + + companion object { + private const val WG_TYPICAL_HANDSHAKE_INTERVAL_WHEN_HEALTHY_SEC = 120 + const val UNHEALTHY_TIME_LIMIT_SEC = WG_TYPICAL_HANDSHAKE_INTERVAL_WHEN_HEALTHY_SEC + 60 + const val NEVER_CONNECTED_TO_UNHEALTHY_TIME_LIMIT_SEC = 30 + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/VpnService.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/VpnService.kt new file mode 100644 index 0000000000..15c8c1b676 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/VpnService.kt @@ -0,0 +1,18 @@ +package net.nymtech.nymconnect.service.tunnel + +import com.wireguard.android.backend.Statistics +import com.wireguard.android.backend.Tunnel +import com.wireguard.crypto.Key +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig +import kotlinx.coroutines.flow.SharedFlow + +interface VpnService : Tunnel { + suspend fun startTunnel(tunnelConfig : TunnelConfig) : Tunnel.State + suspend fun stopTunnel() + val state : SharedFlow + val tunnelName : SharedFlow + val statistics : SharedFlow + val lastHandshake : SharedFlow> + val handshakeStatus : SharedFlow + fun getState() : Tunnel.State +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/WireGuardTunnel.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/WireGuardTunnel.kt new file mode 100644 index 0000000000..ae9a3c233d --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/WireGuardTunnel.kt @@ -0,0 +1,131 @@ +package net.nymtech.nymconnect.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 +import com.wireguard.crypto.Key +import net.nymtech.nymconnect.Constants +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig +import net.nymtech.nymconnect.util.NumberUtils +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import timber.log.Timber +import javax.inject.Inject + + +class WireGuardTunnel @Inject constructor(private val backend : Backend, +) : VpnService { + + private val _tunnelName = MutableStateFlow("") + override val tunnelName get() = _tunnelName.asStateFlow() + + private val _state = MutableSharedFlow( + onBufferOverflow = BufferOverflow.DROP_OLDEST, + replay = 1) + + private val _handshakeStatus = MutableSharedFlow(replay = 1, + onBufferOverflow = BufferOverflow.DROP_OLDEST) + override val state get() = _state.asSharedFlow() + + private val _statistics = MutableSharedFlow(replay = 1) + override val statistics get() = _statistics.asSharedFlow() + + private val _lastHandshake = MutableSharedFlow>(replay = 1) + override val lastHandshake get() = _lastHandshake.asSharedFlow() + + override val handshakeStatus: SharedFlow + get() = _handshakeStatus.asSharedFlow() + + private lateinit var statsJob : Job + + + override suspend fun startTunnel(tunnelConfig: TunnelConfig) : Tunnel.State{ + return try { + if(getState() == Tunnel.State.UP && _tunnelName.value != tunnelConfig.name) { + stopTunnel() + } + _tunnelName.emit(tunnelConfig.name) + val config = TunnelConfig.configFromQuick(tunnelConfig.wgQuick) + val state = backend.setState( + this, Tunnel.State.UP, config) + _state.emit(state) + state; + } catch (e : Exception) { + Timber.e("Failed to start tunnel with error: ${e.message}") + Tunnel.State.DOWN + } + } + + override fun getName(): String { + return _tunnelName.value + } + + override suspend fun stopTunnel() { + try { + if(getState() == Tunnel.State.UP) { + val state = backend.setState(this, Tunnel.State.DOWN, null) + _state.emit(state) + } + } catch (e : BackendException) { + Timber.e("Failed to stop tunnel with error: ${e.message}") + } + } + + override fun getState(): Tunnel.State { + return backend.getState(this) + } + + override fun onStateChange(state : Tunnel.State) { + val tunnel = this; + _state.tryEmit(state) + if(state == Tunnel.State.UP) { + statsJob = CoroutineScope(Dispatchers.IO).launch { + val handshakeMap = HashMap() + var neverHadHandshakeCounter = 0 + while (true) { + val statistics = backend.getStatistics(tunnel) + _statistics.emit(statistics) + statistics.peers().forEach { + val handshakeEpoch = statistics.peer(it)?.latestHandshakeEpochMillis ?: 0L + handshakeMap[it] = handshakeEpoch + if(handshakeEpoch == 0L) { + if(neverHadHandshakeCounter >= HandshakeStatus.NEVER_CONNECTED_TO_UNHEALTHY_TIME_LIMIT_SEC) { + _handshakeStatus.emit(HandshakeStatus.NEVER_CONNECTED) + } else { + _handshakeStatus.emit(HandshakeStatus.NOT_STARTED) + } + if(neverHadHandshakeCounter <= HandshakeStatus.NEVER_CONNECTED_TO_UNHEALTHY_TIME_LIMIT_SEC) { + neverHadHandshakeCounter += 10 + } + return@forEach + } + if(NumberUtils.getSecondsBetweenTimestampAndNow(handshakeEpoch) >= HandshakeStatus.UNHEALTHY_TIME_LIMIT_SEC) { + _handshakeStatus.emit(HandshakeStatus.UNHEALTHY) + } else { + _handshakeStatus.emit(HandshakeStatus.HEALTHY) + } + } + _lastHandshake.emit(handshakeMap) + delay(Constants.VPN_STATISTIC_CHECK_INTERVAL) + } + } + } + if(state == Tunnel.State.DOWN) { + if(this::statsJob.isInitialized) { + statsJob.cancel() + } + _handshakeStatus.tryEmit(HandshakeStatus.NOT_STARTED) + _lastHandshake.tryEmit(emptyMap()) + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/Settings.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/Settings.kt new file mode 100644 index 0000000000..2aff4e9f11 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/Settings.kt @@ -0,0 +1,15 @@ +package net.nymtech.nymconnect.service.tunnel.model + +import io.objectbox.annotation.Entity +import io.objectbox.annotation.Id + +@Entity +data class Settings( + @Id + var id : Long = 0, + var isAutoTunnelEnabled : Boolean = false, + var isTunnelOnMobileDataEnabled : Boolean = false, + var trustedNetworkSSIDs : MutableList = mutableListOf(), + var defaultTunnel : String? = null, + var isAlwaysOnVpnEnabled : Boolean = false, +) diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/TunnelConfig.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/TunnelConfig.kt new file mode 100644 index 0000000000..91f7440d0d --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/service/tunnel/model/TunnelConfig.kt @@ -0,0 +1,89 @@ +package net.nymtech.nymconnect.service.tunnel.model + +import com.wireguard.config.Config +import io.objectbox.annotation.ConflictStrategy +import io.objectbox.annotation.Entity +import io.objectbox.annotation.Id +import io.objectbox.annotation.Unique +import kotlinx.serialization.Serializable +import kotlinx.serialization.json.Json +import java.io.InputStream + + +@Entity +@Serializable +data class TunnelConfig( + @Id + var id : Long = 0, + @Unique(onConflict = ConflictStrategy.REPLACE) + var name : String, + var wgQuick : String +) { + + + override fun toString(): String { + return Json.encodeToString(serializer(), this) + } + + companion object { + private const val INCLUDED_APPLICATIONS = "IncludedApplications = " + private const val EXCLUDED_APPLICATIONS = "ExcludedApplications = " + private const val INTERFACE = "[Interface]" + private const val NEWLINE_CHAR = "\n" + private const val APP_CONFIG_SEPARATOR = ", " + + private fun addApplicationsToConfig(appConfig : String, wgQuick : String) : String { + val configList = wgQuick.split(NEWLINE_CHAR).toMutableList() + val interfaceIndex = configList.indexOf(INTERFACE) + configList.add(interfaceIndex + 1, appConfig) + return configList.joinToString(NEWLINE_CHAR) + } + + fun clearAllApplicationsFromConfig(wgQuick : String) : String { + val configList = wgQuick.split(NEWLINE_CHAR).toMutableList() + val itr = configList.iterator() + while (itr.hasNext()) { + val next = itr.next() + if(next.contains(INCLUDED_APPLICATIONS) || next.contains(EXCLUDED_APPLICATIONS)) { + itr.remove() + } + } + return configList.joinToString(NEWLINE_CHAR) + } + + + fun setExcludedApplicationsOnQuick(packages : List, wgQuick: String) : String { + if(packages.isEmpty()) { + return wgQuick + } + val clearedWgQuick = clearAllApplicationsFromConfig(wgQuick) + val excludeConfig = buildExcludedApplicationsString(packages) + return addApplicationsToConfig(excludeConfig, clearedWgQuick) + } + + fun setIncludedApplicationsOnQuick(packages : List, wgQuick: String) : String { + if(packages.isEmpty()) { + return wgQuick + } + val clearedWgQuick = clearAllApplicationsFromConfig(wgQuick) + val includeConfig = buildIncludedApplicationsString(packages) + return addApplicationsToConfig(includeConfig, clearedWgQuick) + } + + private fun buildExcludedApplicationsString(packages : List) : String { + return EXCLUDED_APPLICATIONS + packages.joinToString(APP_CONFIG_SEPARATOR) + } + + private fun buildIncludedApplicationsString(packages : List) : String { + return INCLUDED_APPLICATIONS + packages.joinToString(APP_CONFIG_SEPARATOR) + } + fun from(string : String) : TunnelConfig { + return Json.decodeFromString(string) + } + fun configFromQuick(wgQuick: String): Config { + val inputStream: InputStream = wgQuick.byteInputStream() + val reader = inputStream.bufferedReader(Charsets.UTF_8) + return Config.parse(reader) + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/MainActivity.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/MainActivity.kt new file mode 100644 index 0000000000..edb82cc213 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/MainActivity.kt @@ -0,0 +1,201 @@ +package net.nymtech.nymconnect.ui + +import android.Manifest +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.provider.Settings +import android.view.KeyEvent +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.compose.setContent +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AppCompatActivity +import androidx.compose.animation.ExperimentalAnimationApi +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.slideInHorizontally +import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.input.key.onKeyEvent +import com.google.accompanist.navigation.animation.AnimatedNavHost +import com.google.accompanist.navigation.animation.composable +import com.google.accompanist.navigation.animation.rememberAnimatedNavController +import com.google.accompanist.permissions.ExperimentalPermissionsApi +import com.google.accompanist.permissions.isGranted +import com.google.accompanist.permissions.rememberPermissionState +import com.wireguard.android.backend.GoBackend +import net.nymtech.nymconnect.R +import net.nymtech.nymconnect.ui.common.PermissionRequestFailedScreen +import net.nymtech.nymconnect.ui.common.navigation.BottomNavBar +import net.nymtech.nymconnect.ui.screens.config.ConfigScreen +import net.nymtech.nymconnect.ui.screens.detail.DetailScreen +import net.nymtech.nymconnect.ui.screens.main.MainScreen +import net.nymtech.nymconnect.ui.screens.settings.SettingsScreen +import net.nymtech.nymconnect.ui.screens.support.SupportScreen +import net.nymtech.nymconnect.ui.theme.TransparentSystemBars +import net.nymtech.nymconnect.ui.theme.WireguardAutoTunnelTheme +import dagger.hilt.android.AndroidEntryPoint +import timber.log.Timber +import java.lang.IllegalStateException + +@AndroidEntryPoint +class MainActivity : AppCompatActivity() { + + @OptIn(ExperimentalAnimationApi::class, + ExperimentalPermissionsApi::class + ) + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + val navController = rememberAnimatedNavController() + val focusRequester = remember { FocusRequester() } + + WireguardAutoTunnelTheme { + TransparentSystemBars() + + val snackbarHostState = remember { SnackbarHostState() } + + val notificationPermissionState = + rememberPermissionState(Manifest.permission.POST_NOTIFICATIONS) + + fun requestNotificationPermission() { + if (!notificationPermissionState.status.isGranted && Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + notificationPermissionState.launchPermissionRequest() + } + } + + var vpnIntent by remember { mutableStateOf(GoBackend.VpnService.prepare(this)) } + val vpnActivityResultState = rememberLauncherForActivityResult( + ActivityResultContracts.StartActivityForResult(), + onResult = { + val accepted = (it.resultCode == RESULT_OK) + if (accepted) { + vpnIntent = null + } + }) + LaunchedEffect(vpnIntent) { + if (vpnIntent != null) { + vpnActivityResultState.launch(vpnIntent) + } else requestNotificationPermission() + } + + Scaffold(snackbarHost = { SnackbarHost(snackbarHostState)}, + modifier = Modifier.onKeyEvent { + if (it.nativeKeyEvent.action == KeyEvent.ACTION_UP) { + when (it.nativeKeyEvent.keyCode) { + KeyEvent.KEYCODE_DPAD_UP -> { + try { + focusRequester.requestFocus() + } catch(e : IllegalStateException) { + Timber.e("No D-Pad focus request modifier added to element on screen") + } + false + } else -> { + false; + } + } + } else { + false + } + }, + bottomBar = if (vpnIntent == null && notificationPermissionState.status.isGranted) { + { BottomNavBar(navController, Routes.navItems) } + } else { + {} + }, + ) + { padding -> + if (vpnIntent != null) { + PermissionRequestFailedScreen( + padding = padding, + onRequestAgain = { vpnActivityResultState.launch(vpnIntent) }, + message = getString(R.string.vpn_permission_required), + getString(R.string.retry) + ) + return@Scaffold + } + if (!notificationPermissionState.status.isGranted) { + PermissionRequestFailedScreen( + padding = padding, + onRequestAgain = { + val intentSettings = + Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) + intentSettings.data = + Uri.fromParts("package", this.packageName, null) + startActivity(intentSettings); + }, + message = getString(R.string.notification_permission_required), + getString(R.string.open_settings) + ) + return@Scaffold + } + AnimatedNavHost(navController, startDestination = Routes.Main.name) { + composable(Routes.Main.name, enterTransition = { + when (initialState.destination.route) { + Routes.Settings.name, Routes.Support.name -> + slideInHorizontally( + initialOffsetX = { -1000 }, + animationSpec = tween(500) + ) + + else -> { + fadeIn(animationSpec = tween(1000)) + } + } + }) { + MainScreen(padding = padding, snackbarHostState = snackbarHostState, navController = navController) + } + composable(Routes.Settings.name, enterTransition = { + when (initialState.destination.route) { + Routes.Main.name -> + slideInHorizontally( + initialOffsetX = { 1000 }, + animationSpec = tween(500) + ) + + Routes.Support.name -> { + slideInHorizontally( + initialOffsetX = { -1000 }, + animationSpec = tween(500) + ) + } + + else -> { + fadeIn(animationSpec = tween(1000)) + } + } + }) { SettingsScreen(padding = padding, snackbarHostState = snackbarHostState, navController = navController, focusRequester = focusRequester) } + composable(Routes.Support.name, enterTransition = { + when (initialState.destination.route) { + Routes.Settings.name, Routes.Main.name -> + slideInHorizontally( + initialOffsetX = { 1000 }, + animationSpec = tween(500) + ) + + else -> { + fadeIn(animationSpec = tween(1000)) + } + } + }) { SupportScreen(padding = padding, focusRequester) } + composable("${Routes.Config.name}/{id}", enterTransition = { + fadeIn(animationSpec = tween(1000)) + }) { ConfigScreen(padding = padding, navController = navController, id = it.arguments?.getString("id"), focusRequester = focusRequester)} + composable("${Routes.Detail.name}/{id}", enterTransition = { + fadeIn(animationSpec = tween(1000)) + }) { DetailScreen(padding = padding, id = it.arguments?.getString("id")) } + } + } + } + } + } +} diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/Routes.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/Routes.kt new file mode 100644 index 0000000000..589fa5fbbf --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/Routes.kt @@ -0,0 +1,36 @@ +package net.nymtech.nymconnect.ui + +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 net.nymtech.nymconnect.ui.common.navigation.BottomNavItem + +enum class Routes { + Main, + Settings, + Support, + Config, + Detail; + + + companion object { + val navItems = listOf( + BottomNavItem( + name = "Tunnels", + route = Main.name, + icon = Icons.Rounded.Home, + ), + BottomNavItem( + name = "Settings", + route = Settings.name, + icon = Icons.Rounded.Settings, + ), + BottomNavItem( + name = "Support", + route = Support.name, + icon = Icons.Rounded.QuestionMark, + ) + ) + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/ViewState.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/ViewState.kt new file mode 100644 index 0000000000..66aa0b8790 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/ViewState.kt @@ -0,0 +1,9 @@ +package net.nymtech.nymconnect.ui + +data class ViewState( + val showSnackbarMessage : Boolean = false, + val snackbarMessage : String = "", + val snackbarActionText : String = "", + val onSnackbarActionClick : () -> Unit = {}, + val isLoading : Boolean = false +) diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/ClickableIconButton.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/ClickableIconButton.kt new file mode 100644 index 0000000000..2ddd1f27b2 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/ClickableIconButton.kt @@ -0,0 +1,31 @@ +package net.nymtech.nymconnect.ui.common + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector + +@Composable +fun ClickableIconButton(onIconClick : () -> Unit, text : String, icon : ImageVector, enabled : Boolean) { + Button(onClick = {}, + enabled = enabled + ) { + Text(text) + Spacer(modifier = Modifier.size(ButtonDefaults.IconSpacing)) + Icon( + imageVector = icon, + contentDescription = "Delete", + modifier = Modifier.size(ButtonDefaults.IconSize).clickable { + if(enabled) { + onIconClick() + } + } + ) + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/PermissionRequestFailedScreen.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/PermissionRequestFailedScreen.kt new file mode 100644 index 0000000000..a0f81b5745 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/PermissionRequestFailedScreen.kt @@ -0,0 +1,35 @@ +package net.nymtech.nymconnect.ui.common + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import kotlinx.coroutines.launch + +@Composable +fun PermissionRequestFailedScreen(padding : PaddingValues, onRequestAgain : () -> Unit, message : String, buttonText : String ) { + val scope = rememberCoroutineScope() + Column(horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + modifier = Modifier + .fillMaxSize() + .padding(padding)) { + Text(message, textAlign = TextAlign.Center, modifier = Modifier.padding(15.dp)) + Button(onClick = { + scope.launch { + onRequestAgain() + } + }) { + Text(buttonText) + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/RowListItem.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/RowListItem.kt new file mode 100644 index 0000000000..33fb6d0bf6 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/RowListItem.kt @@ -0,0 +1,55 @@ +package net.nymtech.nymconnect.ui.common + +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.combinedClickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.unit.dp + +@OptIn(ExperimentalFoundationApi::class) +@Composable +fun RowListItem(leadingIcon : ImageVector? = null, leadingIconColor : Color = Color.Gray, text : String, onHold : () -> Unit, onClick: () -> Unit, rowButton : @Composable() () -> Unit ) { + Box( + modifier = Modifier + .combinedClickable( + onClick = { + onClick() + }, + onLongClick = { + onHold() + } + ) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(14.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Row(verticalAlignment = Alignment.CenterVertically,) { + if(leadingIcon != null) { + Icon( + leadingIcon, "status", + tint = leadingIconColor, + modifier = Modifier.padding(end = 10.dp).size(15.dp) + ) + } + Text(text) + } + + rowButton() + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/SearchBar.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/SearchBar.kt new file mode 100644 index 0000000000..cec26f5b09 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/SearchBar.kt @@ -0,0 +1,80 @@ +package net.nymtech.nymconnect.ui.common + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.Clear +import androidx.compose.material.icons.rounded.Search +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.material3.TextFieldDefaults +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.RectangleShape +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.KeyboardType +import net.nymtech.nymconnect.R + +@Composable +fun SearchBar( + onQuery : (queryString : String) -> Unit +) { + // Immediately update and keep track of query from text field changes. + var query: String by rememberSaveable { mutableStateOf("") } + var showClearIcon by rememberSaveable { mutableStateOf(false) } + + if (query.isEmpty()) { + showClearIcon = false + } else if (query.isNotEmpty()) { + showClearIcon = true + } + + TextField( + value = query, + onValueChange = { onQueryChanged -> + // If user makes changes to text, immediately updated it. + query = onQueryChanged + onQuery(onQueryChanged) + }, + leadingIcon = { + Icon( + imageVector = Icons.Rounded.Search, + tint = MaterialTheme.colorScheme.onBackground, + contentDescription = stringResource(id = R.string.search_icon) + ) + }, + trailingIcon = { + if (showClearIcon) { + IconButton(onClick = { query = "" }) { + Icon( + imageVector = Icons.Rounded.Clear, + tint = MaterialTheme.colorScheme.onBackground, + contentDescription = stringResource(id = R.string.clear_icon) + ) + } + } + }, + maxLines = 1, + colors = TextFieldDefaults.colors( + focusedContainerColor = Color.Transparent, + unfocusedContainerColor = Color.Transparent, + disabledContainerColor = Color.Transparent, + ), + placeholder = { Text(text = stringResource(R.string.hint_search_packages)) }, + textStyle = MaterialTheme.typography.bodySmall, + singleLine = true, + keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text), + modifier = Modifier + .fillMaxWidth() + .background(color = MaterialTheme.colorScheme.background, shape = RectangleShape) + ) +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/navigation/BottomNavBar.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/navigation/BottomNavBar.kt new file mode 100644 index 0000000000..957228eece --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/navigation/BottomNavBar.kt @@ -0,0 +1,42 @@ +package net.nymtech.nymconnect.ui.common.navigation + +import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.NavigationBar +import androidx.compose.material3.NavigationBarItem +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.text.font.FontWeight +import androidx.navigation.NavController +import androidx.navigation.compose.currentBackStackEntryAsState + +@Composable +fun BottomNavBar(navController : NavController, bottomNavItems : List) { + + val backStackEntry = navController.currentBackStackEntryAsState() + + NavigationBar( + containerColor = MaterialTheme.colorScheme.background, + ) { + bottomNavItems.forEach { item -> + val selected = item.route == backStackEntry.value?.destination?.route + + NavigationBarItem( + selected = selected, + onClick = { navController.navigate(item.route) }, + label = { + Text( + text = item.name, + fontWeight = FontWeight.SemiBold, + ) + }, + icon = { + Icon( + imageVector = item.icon, + contentDescription = "${item.name} Icon", + ) + } + ) + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/navigation/BottomNavItem.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/navigation/BottomNavItem.kt new file mode 100644 index 0000000000..a4a585ce5e --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/common/navigation/BottomNavItem.kt @@ -0,0 +1,9 @@ +package net.nymtech.nymconnect.ui.common.navigation + +import androidx.compose.ui.graphics.vector.ImageVector + +data class BottomNavItem( + val name: String, + val route: String, + val icon: ImageVector, +) diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigScreen.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigScreen.kt new file mode 100644 index 0000000000..1ecfaf6570 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigScreen.kt @@ -0,0 +1,241 @@ +package net.nymtech.nymconnect.ui.screens.config + +import android.widget.Toast +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.rounded.Android +import androidx.compose.material3.Button +import androidx.compose.material3.Checkbox +import androidx.compose.material3.Icon +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.ui.Alignment +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardCapitalization +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.NavController +import com.google.accompanist.drawablepainter.DrawablePainter +import net.nymtech.nymconnect.R +import net.nymtech.nymconnect.ui.Routes +import net.nymtech.nymconnect.ui.common.SearchBar +import kotlinx.coroutines.launch + +@OptIn(ExperimentalComposeUiApi::class) +@Composable +fun ConfigScreen( + viewModel: ConfigViewModel = hiltViewModel(), + padding: PaddingValues, + focusRequester: FocusRequester, + navController: NavController, + id : String? +) { + + val context = LocalContext.current + val focusManager = LocalFocusManager.current + + val keyboardController = LocalSoftwareKeyboardController.current + val scope = rememberCoroutineScope() + val tunnel by viewModel.tunnel.collectAsStateWithLifecycle(null) + val tunnelName = viewModel.tunnelName.collectAsStateWithLifecycle() + val packages by viewModel.packages.collectAsStateWithLifecycle() + val checkedPackages by viewModel.checkedPackages.collectAsStateWithLifecycle() + val include by viewModel.include.collectAsStateWithLifecycle() + val allApplications by viewModel.allApplications.collectAsStateWithLifecycle() + + LaunchedEffect(Unit) { + viewModel.getTunnelById(id) + viewModel.emitQueriedPackages("") + viewModel.emitCurrentPackageConfigurations(id) + } + + if(tunnel != null) { + LazyColumn( + horizontalAlignment = Alignment.Start, + verticalArrangement = Arrangement.Top, + modifier = Modifier + .fillMaxSize() + .padding(padding) + ) { + item { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp, vertical = 7.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + OutlinedTextField( + modifier = Modifier.focusRequester(focusRequester), + value = tunnelName.value, + onValueChange = { + viewModel.onTunnelNameChange(it) + }, + label = { Text(stringResource(id = R.string.tunnel_name)) }, + maxLines = 1, + keyboardOptions = KeyboardOptions( + capitalization = KeyboardCapitalization.None, + imeAction = ImeAction.Done + ), + keyboardActions = KeyboardActions( + onDone = { + focusManager.clearFocus() + keyboardController?.hide() + viewModel.onTunnelNameChange(tunnelName.value) + } + ), + ) + } + } + item { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp, vertical = 7.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text(stringResource(id = R.string.tunnel_all)) + Switch( + checked = allApplications, + onCheckedChange = { + viewModel.onAllApplicationsChange(!allApplications) + } + ) + } + } + if (!allApplications) { + item { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp, vertical = 7.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text(stringResource(id = R.string.include)) + Checkbox( + checked = include, + onCheckedChange = { + viewModel.onIncludeChange(!include) + } + ) + } + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text(stringResource(id = R.string.exclude)) + Checkbox( + checked = !include, + onCheckedChange = { + viewModel.onIncludeChange(!include) + } + ) + } + } + } + item { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp, vertical = 7.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween) { + SearchBar(viewModel::emitQueriedPackages); + } + } + items(packages) { pack -> + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Row( + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.padding(5.dp) + ) { + val drawable = + pack.applicationInfo?.loadIcon(context.packageManager) + if (drawable != null) { + Image( + painter = DrawablePainter(drawable), + stringResource(id = R.string.icon), + modifier = Modifier.size(50.dp, 50.dp) + ) + } else { + Icon( + Icons.Rounded.Android, + stringResource(id = R.string.edit), + modifier = Modifier.size(50.dp, 50.dp) + ) + } + Text( + pack.applicationInfo.loadLabel(context.packageManager) + .toString(), modifier = Modifier.padding(5.dp) + ) + } + Checkbox( + checked = (checkedPackages.contains(pack.packageName)), + onCheckedChange = { + if (it) viewModel.onAddCheckedPackage(pack.packageName) else viewModel.onRemoveCheckedPackage( + pack.packageName + ) + } + ) + } + } + } + item { + Row( + horizontalArrangement = Arrangement.Center, + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth() + ) { + Button(onClick = { + scope.launch { + viewModel.onSaveAllChanges() + Toast.makeText( + context, + context.resources.getString(R.string.config_changes_saved), + Toast.LENGTH_LONG + ).show() + navController.navigate(Routes.Main.name) + } + }, Modifier.padding(25.dp)) { + Text(stringResource(id = R.string.save_changes)) + } + } + } + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigViewModel.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigViewModel.kt new file mode 100644 index 0000000000..325e5a49bd --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/config/ConfigViewModel.kt @@ -0,0 +1,152 @@ +package net.nymtech.nymconnect.ui.screens.config + +import android.Manifest +import android.app.Application +import android.content.pm.PackageInfo +import android.content.pm.PackageManager +import android.os.Build +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.toMutableStateList +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import net.nymtech.nymconnect.repository.Repository +import net.nymtech.nymconnect.service.tunnel.model.Settings +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import timber.log.Timber +import javax.inject.Inject + +@HiltViewModel +class ConfigViewModel @Inject constructor(private val application : Application, + private val tunnelRepo : Repository, + private val settingsRepo : Repository) : ViewModel() { + + private val _tunnel = MutableStateFlow(null) + private val _tunnelName = MutableStateFlow("") + val tunnelName get() = _tunnelName.asStateFlow() + val tunnel get() = _tunnel.asStateFlow() + private val _packages = MutableStateFlow(emptyList()) + val packages get() = _packages.asStateFlow() + private val packageManager = application.packageManager + + private val _checkedPackages = MutableStateFlow(mutableStateListOf()) + val checkedPackages get() = _checkedPackages.asStateFlow() + private val _include = MutableStateFlow(true) + val include get() = _include.asStateFlow() + + private val _allApplications = MutableStateFlow(true) + val allApplications get() = _allApplications.asStateFlow() + + suspend fun getTunnelById(id : String?) : TunnelConfig? { + return try { + if(id != null) { + val config = tunnelRepo.getById(id.toLong()) + if (config != null) { + _tunnel.emit(config) + _tunnelName.emit(config.name) + + } + return config + } + return null + } catch (e : Exception) { + Timber.e(e.message) + null + } + } + + fun onTunnelNameChange(name : String) { + _tunnelName.value = name + } + + fun onIncludeChange(include : Boolean) { + _include.value = include + } + fun onAddCheckedPackage(packageName : String) { + _checkedPackages.value.add(packageName) + } + + fun onAllApplicationsChange(allApplications : Boolean) { + _allApplications.value = allApplications + } + + fun onRemoveCheckedPackage(packageName : String) { + _checkedPackages.value.remove(packageName) + } + + suspend fun emitCurrentPackageConfigurations(id : String?) { + val tunnelConfig = getTunnelById(id) + if(tunnelConfig != null) { + val config = TunnelConfig.configFromQuick(tunnelConfig.wgQuick) + val excludedApps = config.`interface`.excludedApplications + val includedApps = config.`interface`.includedApplications + if(excludedApps.isNullOrEmpty() && includedApps.isNullOrEmpty()) { + _allApplications.emit(true) + return + } + if(excludedApps.isEmpty()) { + _include.emit(true) + _checkedPackages.emit(includedApps.toMutableStateList()) + } else { + _include.emit(false) + _checkedPackages.emit(excludedApps.toMutableStateList()) + } + _allApplications.emit(false) + } + } + + fun emitQueriedPackages(query : String) { + viewModelScope.launch { + _packages.emit(getAllInternetCapablePackages().filter { + it.packageName.contains(query) + }) + } + } + + private fun getAllInternetCapablePackages() : List { + return getPackagesHoldingPermissions(arrayOf(Manifest.permission.INTERNET)) + } + + private fun getPackagesHoldingPermissions(permissions: Array): List { + return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + packageManager.getPackagesHoldingPermissions(permissions, PackageManager.PackageInfoFlags.of(0L)) + } else { + @Suppress("DEPRECATION") + packageManager.getPackagesHoldingPermissions(permissions, 0) + } + } + + suspend fun onSaveAllChanges() { + var wgQuick = _tunnel.value?.wgQuick + if(wgQuick != null) { + wgQuick = if(_include.value) { + TunnelConfig.setIncludedApplicationsOnQuick(_checkedPackages.value, wgQuick) + } else { + TunnelConfig.setExcludedApplicationsOnQuick(_checkedPackages.value, wgQuick) + } + if(_allApplications.value) { + wgQuick = TunnelConfig.clearAllApplicationsFromConfig(wgQuick) + } + _tunnel.value?.copy( + name = _tunnelName.value, + wgQuick = wgQuick + )?.let { + tunnelRepo.save(it) + val settings = settingsRepo.getAll() + if(settings != null) { + val setting = settings[0] + if(setting.defaultTunnel != null) { + if(it.id == TunnelConfig.from(setting.defaultTunnel!!).id) { + settingsRepo.save(setting.copy( + defaultTunnel = it.toString() + )) + } + } + } + } + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/detail/DetailScreen.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/detail/DetailScreen.kt new file mode 100644 index 0000000000..bdf77a5e56 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/detail/DetailScreen.kt @@ -0,0 +1,139 @@ +package net.nymtech.nymconnect.ui.screens.detail + +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.ClipboardManager +import androidx.compose.ui.platform.LocalClipboardManager +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.AnnotatedString +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import net.nymtech.nymconnect.R +import net.nymtech.nymconnect.util.NumberUtils +import java.time.Duration +import java.time.Instant + +@Composable +fun DetailScreen( + viewModel: DetailViewModel = hiltViewModel(), + padding: PaddingValues, + id : String? +) { + + val clipboardManager: ClipboardManager = LocalClipboardManager.current + val tunnelStats by viewModel.tunnelStats.collectAsStateWithLifecycle(null) + val tunnel by viewModel.tunnel.collectAsStateWithLifecycle(null) + val tunnelName by viewModel.tunnelName.collectAsStateWithLifecycle() + val lastHandshake by viewModel.lastHandshake.collectAsStateWithLifecycle(emptyMap()) + + + LaunchedEffect(Unit) { + viewModel.getTunnelById(id) + } + + if(tunnel != null) { + val interfaceKey = tunnel?.`interface`?.keyPair?.publicKey?.toBase64().toString() + val addresses = tunnel?.`interface`?.addresses!!.joinToString() + val dnsServers = tunnel?.`interface`?.dnsServers!!.joinToString() + val optionalMtu = tunnel?.`interface`?.mtu + val mtu = if(optionalMtu?.isPresent == true) optionalMtu.get().toString() else "None" + Column( + horizontalAlignment = Alignment.Start, + verticalArrangement = Arrangement.Top, + modifier = Modifier + .fillMaxSize() + .verticalScroll(rememberScrollState()) + .padding(padding) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 20.dp, vertical = 7.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Column { + Text(stringResource(R.string.config_interface), fontWeight = FontWeight.Bold, fontSize = 20.sp) + Text(stringResource(R.string.name), fontStyle = FontStyle.Italic) + Text(text = tunnelName, modifier = Modifier.clickable { + clipboardManager.setText(AnnotatedString(tunnelName)) + }) + Text(stringResource(R.string.public_key), fontStyle = FontStyle.Italic) + Text(text = interfaceKey, modifier = Modifier.clickable { + clipboardManager.setText(AnnotatedString(interfaceKey)) + }) + Text(stringResource(R.string.addresses), fontStyle = FontStyle.Italic) + Text(text = addresses, modifier = Modifier.clickable { + clipboardManager.setText(AnnotatedString(addresses)) + }) + Text(stringResource(R.string.dns_servers), fontStyle = FontStyle.Italic) + Text(text = dnsServers, modifier = Modifier.clickable { + clipboardManager.setText(AnnotatedString(dnsServers)) + }) + Text(stringResource(R.string.mtu), fontStyle = FontStyle.Italic) + Text(text = mtu, modifier = Modifier.clickable { + clipboardManager.setText(AnnotatedString(mtu)) + }) + Box(modifier = Modifier.padding(10.dp)) + tunnel?.peers?.forEach{ + val peerKey = it.publicKey.toBase64().toString() + val allowedIps = it.allowedIps.joinToString() + val endpoint = if(it.endpoint.isPresent) it.endpoint.get().toString() else "None" + Text(stringResource(R.string.peer), fontWeight = FontWeight.Bold, fontSize = 20.sp) + Text(stringResource(R.string.public_key), fontStyle = FontStyle.Italic) + Text(text = peerKey, modifier = Modifier.clickable { + clipboardManager.setText(AnnotatedString(peerKey)) + }) + Text(stringResource(id = R.string.allowed_ips), fontStyle = FontStyle.Italic) + Text(text = allowedIps, modifier = Modifier.clickable { + clipboardManager.setText(AnnotatedString(allowedIps)) + }) + Text(stringResource(R.string.endpoint), fontStyle = FontStyle.Italic) + Text(text = endpoint, modifier = Modifier.clickable { + clipboardManager.setText(AnnotatedString(endpoint)) + }) + if (tunnelStats != null) { + val totalRx = tunnelStats?.totalRx() ?: 0 + val totalTx = tunnelStats?.totalTx() ?: 0 + if((totalRx + totalTx != 0L)) { + val rxKB = NumberUtils.bytesToKB(tunnelStats!!.totalRx()) + val txKB = NumberUtils.bytesToKB(tunnelStats!!.totalTx()) + Text(stringResource(R.string.transfer), fontStyle = FontStyle.Italic) + Text("rx: ${NumberUtils.formatDecimalTwoPlaces(rxKB)} KB tx: ${NumberUtils.formatDecimalTwoPlaces(txKB)} KB") + Text(stringResource(R.string.last_handshake), fontStyle = FontStyle.Italic) + val handshakeEpoch = lastHandshake[it.publicKey] + if(handshakeEpoch != null) { + if(handshakeEpoch == 0L) { + Text("Never") + } else { + val time = Instant.ofEpochMilli(handshakeEpoch) + Text("${Duration.between(time, Instant.now()).seconds} seconds ago") + } + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/detail/DetailViewModel.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/detail/DetailViewModel.kt new file mode 100644 index 0000000000..cf83878a0b --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/detail/DetailViewModel.kt @@ -0,0 +1,45 @@ +package net.nymtech.nymconnect.ui.screens.detail + +import androidx.lifecycle.ViewModel +import com.wireguard.config.Config +import net.nymtech.nymconnect.repository.Repository +import net.nymtech.nymconnect.service.tunnel.VpnService +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import timber.log.Timber +import javax.inject.Inject + +@HiltViewModel +class DetailViewModel @Inject constructor(private val tunnelRepo : Repository, private val vpnService : VpnService + +) : ViewModel() { + + private val _tunnel = MutableStateFlow(null) + val tunnel get() = _tunnel.asStateFlow() + + private val _tunnelName = MutableStateFlow("") + val tunnelName = _tunnelName.asStateFlow() + val tunnelStats get() = vpnService.statistics + val lastHandshake get() = vpnService.lastHandshake + + private var config : TunnelConfig? = null + + suspend fun getTunnelById(id : String?) : TunnelConfig? { + return try { + if(id != null) { + config = tunnelRepo.getById(id.toLong()) + if (config != null) { + _tunnel.emit(TunnelConfig.configFromQuick(config!!.wgQuick)) + _tunnelName.emit(config!!.name) + } + return config + } + return null + } catch (e : Exception) { + Timber.e(e.message) + null + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt new file mode 100644 index 0000000000..e2abdd07b7 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainScreen.kt @@ -0,0 +1,336 @@ +package net.nymtech.nymconnect.ui.screens.main + +import android.annotation.SuppressLint +import androidx.activity.compose.rememberLauncherForActivityResult +import androidx.activity.result.contract.ActivityResultContracts +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.slideInVertically +import androidx.compose.animation.slideOutVertically +import androidx.compose.foundation.clickable +import androidx.compose.foundation.focusable +import androidx.compose.foundation.gestures.detectTapGestures +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.FileOpen +import androidx.compose.material.icons.rounded.Add +import androidx.compose.material.icons.rounded.Circle +import androidx.compose.material.icons.rounded.Delete +import androidx.compose.material.icons.rounded.Edit +import androidx.compose.material.icons.rounded.Info +import androidx.compose.material3.Divider +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.FabPosition +import androidx.compose.material3.FloatingActionButton +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarDuration +import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.SnackbarResult +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +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 +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.unit.dp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.NavController +import com.wireguard.android.backend.Tunnel +import net.nymtech.nymconnect.R +import net.nymtech.nymconnect.WireGuardAutoTunnel +import net.nymtech.nymconnect.service.tunnel.HandshakeStatus +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig +import net.nymtech.nymconnect.ui.Routes +import net.nymtech.nymconnect.ui.common.RowListItem +import net.nymtech.nymconnect.ui.theme.brickRed +import net.nymtech.nymconnect.ui.theme.mint +import kotlinx.coroutines.launch + +@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MainScreen( + viewModel: MainViewModel = hiltViewModel(), padding: PaddingValues, + snackbarHostState: SnackbarHostState, navController: NavController +) { + + val haptic = LocalHapticFeedback.current + val context = LocalContext.current + val isVisible = rememberSaveable { mutableStateOf(true) } + val scope = rememberCoroutineScope() + + val sheetState = rememberModalBottomSheetState() + var showBottomSheet by remember { mutableStateOf(false) } + val tunnels by viewModel.tunnels.collectAsStateWithLifecycle(mutableListOf()) + val handshakeStatus by viewModel.handshakeStatus.collectAsStateWithLifecycle(HandshakeStatus.NOT_STARTED) + val viewState = viewModel.viewState.collectAsStateWithLifecycle() + var selectedTunnel by remember { mutableStateOf(null) } + val state by viewModel.state.collectAsStateWithLifecycle(Tunnel.State.DOWN) + val tunnelName by viewModel.tunnelName.collectAsStateWithLifecycle("") + + // 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 + } + } + } + + LaunchedEffect(viewState.value) { + if (viewState.value.showSnackbarMessage) { + val result = snackbarHostState.showSnackbar( + message = viewState.value.snackbarMessage, + actionLabel = viewState.value.snackbarActionText, + duration = SnackbarDuration.Long, + ) + when (result) { + SnackbarResult.ActionPerformed -> viewState.value.onSnackbarActionClick + SnackbarResult.Dismissed -> viewState.value.onSnackbarActionClick + } + } + } + + val pickFileLauncher = rememberLauncherForActivityResult( + ActivityResultContracts.GetContent() + ) { file -> + if (file != null) { + viewModel.onTunnelFileSelected(file) + } + } + + Scaffold( + modifier = Modifier.pointerInput(Unit) { + detectTapGestures(onTap = { + selectedTunnel = null + }) + }, + floatingActionButtonPosition = FabPosition.End, + floatingActionButton = { + AnimatedVisibility( + visible = isVisible.value, + enter = slideInVertically(initialOffsetY = { it * 2 }), + exit = slideOutVertically(targetOffsetY = { it * 2 }), + ) { + FloatingActionButton( + modifier = Modifier.padding(bottom = 90.dp), + onClick = { + showBottomSheet = true + }, + containerColor = MaterialTheme.colorScheme.secondary, + shape = RoundedCornerShape(16.dp), + ) { + Icon( + imageVector = Icons.Rounded.Add, + contentDescription = stringResource(id = R.string.add_tunnel), + tint = Color.DarkGray, + ) + } + } + } + ) { + if (tunnels.isEmpty()) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + modifier = Modifier + .fillMaxSize() + .padding(padding) + ) { + Text(text = stringResource(R.string.no_tunnels), fontStyle = FontStyle.Italic) + } + } + if (showBottomSheet) { + ModalBottomSheet( + onDismissRequest = { + showBottomSheet = false + }, + sheetState = sheetState + ) { + // Sheet content + Row( + modifier = Modifier + .fillMaxWidth() + .clickable { + showBottomSheet = false + pickFileLauncher.launch("*/*") + } + .padding(10.dp) + ) { + Icon( + Icons.Filled.FileOpen, + contentDescription = stringResource(id = R.string.open_file), + modifier = Modifier.padding(10.dp) + ) + Text( + stringResource(id = R.string.add_from_file), + modifier = Modifier.padding(10.dp) + ) + } + Divider() + } + } + Column( + horizontalAlignment = Alignment.Start, + verticalArrangement = Arrangement.Top, + modifier = Modifier + .fillMaxSize() + .padding(padding) + ) { + + LazyColumn( + modifier = Modifier.fillMaxSize() + .nestedScroll(nestedScrollConnection), + ) { + itemsIndexed(tunnels.toList()) { index, tunnel -> + val focusRequester = FocusRequester(); + RowListItem(leadingIcon = Icons.Rounded.Circle, + leadingIconColor = if (tunnelName == tunnel.name) when (handshakeStatus) { + HandshakeStatus.HEALTHY -> mint + HandshakeStatus.UNHEALTHY -> brickRed + HandshakeStatus.NOT_STARTED -> Color.Gray + HandshakeStatus.NEVER_CONNECTED -> brickRed + } else Color.Gray, + text = tunnel.name, + onHold = { + if (state == Tunnel.State.UP && tunnel.name == tunnelName) { + scope.launch { + viewModel.showSnackBarMessage(context.resources.getString(R.string.turn_off_tunnel)) + } + return@RowListItem + } + haptic.performHapticFeedback(HapticFeedbackType.LongPress) + selectedTunnel = tunnel; + }, + onClick = { + if (!WireGuardAutoTunnel.isRunningOnAndroidTv(context)) { + navController.navigate("${Routes.Detail.name}/${tunnel.id}") + } else { + focusRequester.requestFocus() + } + }, + rowButton = { + if (tunnel.id == selectedTunnel?.id) { + Row { + IconButton(onClick = { + navController.navigate("${Routes.Config.name}/${selectedTunnel?.id}") + }) { + Icon(Icons.Rounded.Edit, stringResource(id = R.string.edit)) + } + IconButton( + modifier = Modifier.focusable(), + onClick = { viewModel.onDelete(tunnel) }) { + Icon( + Icons.Rounded.Delete, + stringResource(id = R.string.delete) + ) + } + } + } else { + if (WireGuardAutoTunnel.isRunningOnAndroidTv(context)) { + Row { + IconButton( + modifier = Modifier.focusRequester(focusRequester), + onClick = { + navController.navigate("${Routes.Detail.name}/${tunnel.id}") + }) { + Icon(Icons.Rounded.Info, "Info") + } + IconButton(onClick = { + if (state == Tunnel.State.UP && tunnel.name == tunnelName) + scope.launch { + viewModel.showSnackBarMessage( + context.resources.getString( + R.string.turn_off_tunnel + ) + ) + } else { + navController.navigate("${Routes.Config.name}/${tunnel.id}") + } + }) { + Icon( + Icons.Rounded.Edit, + stringResource(id = R.string.edit) + ) + } + IconButton(onClick = { + if (state == Tunnel.State.UP && tunnel.name == tunnelName) + scope.launch { + viewModel.showSnackBarMessage( + context.resources.getString( + R.string.turn_off_tunnel + ) + ) + } else { + viewModel.onDelete(tunnel) + } + }) { + Icon( + Icons.Rounded.Delete, + stringResource(id = R.string.delete) + ) + } + Switch( + checked = (state == Tunnel.State.UP && tunnel.name == tunnelName), + onCheckedChange = { checked -> + if (checked) viewModel.onTunnelStart(tunnel) else viewModel.onTunnelStop() + } + ) + } + } else { + Switch( + checked = (state == Tunnel.State.UP && tunnel.name == tunnelName), + onCheckedChange = { checked -> + if (checked) viewModel.onTunnelStart(tunnel) else viewModel.onTunnelStop() + } + ) + } + } + }) + } + } + } + } +} diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt new file mode 100644 index 0000000000..a88b5adcb9 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/main/MainViewModel.kt @@ -0,0 +1,179 @@ +package net.nymtech.nymconnect.ui.screens.main + +import android.annotation.SuppressLint +import android.app.Application +import android.content.Context +import android.net.Uri +import android.provider.OpenableColumns +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.wireguard.config.BadConfigException +import com.wireguard.config.Config +import net.nymtech.nymconnect.R +import net.nymtech.nymconnect.repository.Repository +import net.nymtech.nymconnect.service.foreground.ServiceState +import net.nymtech.nymconnect.service.foreground.ServiceManager +import net.nymtech.nymconnect.service.foreground.WireGuardConnectivityWatcherService +import net.nymtech.nymconnect.service.shortcut.ShortcutsManager +import net.nymtech.nymconnect.service.tunnel.VpnService +import net.nymtech.nymconnect.service.tunnel.model.Settings +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig +import net.nymtech.nymconnect.ui.ViewState +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import timber.log.Timber +import javax.inject.Inject + + +@HiltViewModel +class MainViewModel @Inject constructor(private val application : Application, + private val tunnelRepo : Repository, + private val settingsRepo : Repository, + private val vpnService: VpnService, +) : ViewModel() { + + private val _viewState = MutableStateFlow(ViewState()) + val viewState get() = _viewState.asStateFlow() + val tunnels get() = tunnelRepo.itemFlow + val state get() = vpnService.state + + val handshakeStatus get() = vpnService.handshakeStatus + val tunnelName get() = vpnService.tunnelName + private val _settings = MutableStateFlow(Settings()) + val settings get() = _settings.asStateFlow() + + private val defaultConfigName = { + "tunnel${(Math.random() * 100000).toInt()}" + } + + + init { + viewModelScope.launch { + settingsRepo.itemFlow.collect { + val settings = it.first() + validateWatcherServiceState(settings) + _settings.emit(settings) + } + } + } + + private fun validateWatcherServiceState(settings: Settings) { + val watcherState = ServiceManager.getServiceState(application.applicationContext, WireGuardConnectivityWatcherService::class.java) + if(settings.isAutoTunnelEnabled && watcherState == ServiceState.STOPPED && settings.defaultTunnel != null) { + ServiceManager.startWatcherService(application.applicationContext, settings.defaultTunnel!!) + } + } + + + fun onDelete(tunnel : TunnelConfig) { + viewModelScope.launch { + if(tunnelRepo.count() == 1L) { + ServiceManager.stopWatcherService(application.applicationContext) + val settings = settingsRepo.getAll() + if(!settings.isNullOrEmpty()) { + val setting = settings[0] + setting.defaultTunnel = null + setting.isAutoTunnelEnabled = false + setting.isAlwaysOnVpnEnabled = false + settingsRepo.save(setting) + } + } + tunnelRepo.delete(tunnel) + ShortcutsManager.removeTunnelShortcuts(application.applicationContext, tunnel) + } + } + + fun onTunnelStart(tunnelConfig : TunnelConfig) = viewModelScope.launch { + ServiceManager.startVpnService(application.applicationContext, tunnelConfig.toString()) + } + + fun onTunnelStop() { + ServiceManager.stopVpnService(application.applicationContext) + } + + fun onTunnelFileSelected(uri : Uri) { + try { + val fileName = getFileName(application.applicationContext, uri) + val extension = getFileExtensionFromFileName(fileName) + if(extension != ".conf") { + viewModelScope.launch { + showSnackBarMessage(application.resources.getString(R.string.file_extension_message)) + } + return + } + val stream = application.applicationContext.contentResolver.openInputStream(uri) + stream ?: return + val bufferReader = stream.bufferedReader(charset = Charsets.UTF_8) + val config = Config.parse(bufferReader) + val tunnelName = getNameFromFileName(fileName) + saveTunnel(TunnelConfig(name = tunnelName, wgQuick = config.toWgQuickString())) + stream.close() + } catch(_: BadConfigException) { + viewModelScope.launch { + showSnackBarMessage(application.applicationContext.getString(R.string.bad_config)) + } + } + } + + private fun saveTunnel(tunnelConfig : TunnelConfig) { + viewModelScope.launch { + tunnelRepo.save(tunnelConfig) + ShortcutsManager.createTunnelShortcuts(application.applicationContext, tunnelConfig) + } + } + + @SuppressLint("Range") + private fun getFileName(context: Context, uri: Uri): String { + if (uri.scheme == "content") { + val cursor = try { + context.contentResolver.query(uri, null, null, null, null) + } catch (e : Exception) { + Timber.d("Exception getting config name") + null + } + cursor ?: return defaultConfigName() + cursor.use { + if(cursor.moveToFirst()) { + return cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME)) + } + } + } + return defaultConfigName() + } + + suspend fun showSnackBarMessage(message : String) { + _viewState.emit(_viewState.value.copy( + showSnackbarMessage = true, + snackbarMessage = message, + snackbarActionText = "Okay", + onSnackbarActionClick = { + viewModelScope.launch { + dismissSnackBar() + } + } + )) + delay(3000) + dismissSnackBar() + } + + private suspend fun dismissSnackBar() { + _viewState.emit(_viewState.value.copy( + showSnackbarMessage = false + )) + } + + private fun getNameFromFileName(fileName : String) : String { + return fileName.substring(0 , fileName.lastIndexOf('.') ) + } + + private fun getFileExtensionFromFileName(fileName : String) : String { + return try { + fileName.substring(fileName.lastIndexOf('.')) + } catch (e : Exception) { + "" + } + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt new file mode 100644 index 0000000000..4616a8fd9a --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsScreen.kt @@ -0,0 +1,415 @@ +package net.nymtech.nymconnect.ui.screens.settings + +import android.Manifest +import android.content.Intent +import android.net.Uri +import android.os.Build +import android.provider.Settings +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Close +import androidx.compose.material.icons.outlined.Add +import androidx.compose.material.icons.rounded.LocationOff +import androidx.compose.material3.Button +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.ExposedDropdownMenuBox +import androidx.compose.material3.ExposedDropdownMenuDefaults +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.SnackbarDuration +import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.SnackbarResult +import androidx.compose.material3.Switch +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.KeyboardCapitalization +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.NavController +import com.google.accompanist.permissions.ExperimentalPermissionsApi +import com.google.accompanist.permissions.isGranted +import com.google.accompanist.permissions.rememberPermissionState +import net.nymtech.nymconnect.R +import net.nymtech.nymconnect.WireGuardAutoTunnel +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig +import net.nymtech.nymconnect.ui.Routes +import net.nymtech.nymconnect.ui.common.ClickableIconButton +import kotlinx.coroutines.launch + +@OptIn(ExperimentalMaterial3Api::class, ExperimentalPermissionsApi::class, + ExperimentalLayoutApi::class +) +@Composable +fun SettingsScreen( + viewModel: SettingsViewModel = hiltViewModel(), + padding: PaddingValues, + navController: NavController, + focusRequester: FocusRequester, + snackbarHostState: SnackbarHostState = remember { SnackbarHostState() } +) { + + val scope = rememberCoroutineScope() + val context = LocalContext.current + val focusManager = LocalFocusManager.current + val interactionSource = remember { MutableInteractionSource() } + + var expanded by remember { mutableStateOf(false) } + val viewState by viewModel.viewState.collectAsStateWithLifecycle() + val settings by viewModel.settings.collectAsStateWithLifecycle() + val trustedSSIDs by viewModel.trustedSSIDs.collectAsStateWithLifecycle() + val tunnels by viewModel.tunnels.collectAsStateWithLifecycle(mutableListOf()) + val backgroundLocationState = + rememberPermissionState(Manifest.permission.ACCESS_BACKGROUND_LOCATION) + val fineLocationState = rememberPermissionState(Manifest.permission.ACCESS_FINE_LOCATION) + var currentText by remember { mutableStateOf("") } + val scrollState = rememberScrollState() + var isLocationServicesEnabled by remember { mutableStateOf(viewModel.checkLocationServicesEnabled())} + + LaunchedEffect(viewState) { + if (viewState.showSnackbarMessage) { + val result = snackbarHostState.showSnackbar( + message = viewState.snackbarMessage, + actionLabel = viewState.snackbarActionText, + duration = SnackbarDuration.Long, + ) + when (result) { + SnackbarResult.ActionPerformed -> viewState.onSnackbarActionClick + SnackbarResult.Dismissed -> viewState.onSnackbarActionClick + } + } + } + + fun saveTrustedSSID() { + if (currentText.isNotEmpty()) { + scope.launch { + viewModel.onSaveTrustedSSID(currentText) + currentText = "" + } + } + } + + fun openSettings() { + scope.launch { + val intentSettings = + Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) + intentSettings.data = + Uri.fromParts("package", context.packageName, null) + context.startActivity(intentSettings) + } + } + + if(!backgroundLocationState.status.isGranted && Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + Column(horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Top, + modifier = Modifier + .fillMaxSize() + .verticalScroll(scrollState) + .padding(padding)) { + Icon(Icons.Rounded.LocationOff, contentDescription = stringResource(id = R.string.map), modifier = Modifier + .padding(30.dp) + .size(128.dp)) + Text(stringResource(R.string.prominent_background_location_title), textAlign = TextAlign.Center, modifier = Modifier.padding(30.dp), fontSize = 20.sp) + Text(stringResource(R.string.prominent_background_location_message), textAlign = TextAlign.Center, modifier = Modifier.padding(30.dp), fontSize = 15.sp) + Row( + modifier = if(WireGuardAutoTunnel.isRunningOnAndroidTv(context)) Modifier + .fillMaxWidth() + .padding(10.dp) else Modifier + .fillMaxWidth() + .padding(30.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceEvenly + ) { + Button(onClick = { + navController.navigate(Routes.Main.name) + }) { + Text(stringResource(id = R.string.no_thanks)) + } + Button(modifier = Modifier.focusRequester(focusRequester), onClick = { + openSettings() + }) { + Text(stringResource(id = R.string.turn_on)) + } + } + } + return + } + + if(!fineLocationState.status.isGranted) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + modifier = Modifier + .fillMaxSize() + .padding(padding) + ) { + Text( + stringResource(id = R.string.precise_location_message), + textAlign = TextAlign.Center, + modifier = Modifier.padding(15.dp), + fontStyle = FontStyle.Italic + ) + Button(modifier = Modifier.focusRequester(focusRequester),onClick = { + fineLocationState.launchPermissionRequest() + }) { + Text(stringResource(id = R.string.request)) + } + + } + return + } + + if (tunnels.isEmpty()) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + modifier = Modifier + .fillMaxSize() + .padding(padding) + ) { + Text( + stringResource(R.string.one_tunnel_required), + textAlign = TextAlign.Center, + modifier = Modifier.padding(15.dp), + fontStyle = FontStyle.Italic + ) + } + return + } + if(!isLocationServicesEnabled && Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { + Column( + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + modifier = Modifier + .fillMaxSize() + .padding(padding) + ) { + Text( + stringResource(id = R.string.location_services_not_detected), + textAlign = TextAlign.Center, + modifier = Modifier.padding(15.dp), + fontStyle = FontStyle.Italic + ) + Button(modifier = Modifier.focusRequester(focusRequester), onClick = { + val locationServicesEnabled = viewModel.checkLocationServicesEnabled() + isLocationServicesEnabled = locationServicesEnabled + if(!locationServicesEnabled) { + scope.launch { + viewModel.showSnackBarMessage(context.getString(R.string.detecting_location_services_disabled)) + } + } + }) { + Text(stringResource(id = R.string.check_again)) + } + } + return + } + val screenPadding = if(WireGuardAutoTunnel.isRunningOnAndroidTv(context)) 5.dp else 15.dp + Column( + horizontalAlignment = Alignment.Start, + verticalArrangement = Arrangement.Top, + modifier = if(WireGuardAutoTunnel.isRunningOnAndroidTv(context)) Modifier + .fillMaxHeight(.85f) + .fillMaxWidth() + .verticalScroll(scrollState) + .clickable(indication = null, interactionSource = interactionSource) { + focusManager.clearFocus() + } + .padding(padding) else Modifier + .fillMaxSize() + .verticalScroll(scrollState) + .clickable(indication = null, interactionSource = interactionSource) { + focusManager.clearFocus() + } + .padding(padding) + ) { + Row( + modifier = Modifier + .fillMaxWidth() + .padding(screenPadding), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text(stringResource(R.string.enable_auto_tunnel)) + Switch( + modifier = Modifier.focusRequester(focusRequester), + enabled = !settings.isAlwaysOnVpnEnabled, + checked = settings.isAutoTunnelEnabled, + onCheckedChange = { + scope.launch { + viewModel.toggleAutoTunnel() + } + } + ) + } + Text( + stringResource(id = R.string.select_tunnel), + textAlign = TextAlign.Center, + modifier = Modifier.padding(screenPadding, bottom = 5.dp, top = 5.dp) + ) + ExposedDropdownMenuBox( + expanded = expanded, + onExpandedChange = { + if(!(settings.isAutoTunnelEnabled || settings.isAlwaysOnVpnEnabled)) { + expanded = !expanded }}, + modifier = Modifier.padding(start = 15.dp, top = 5.dp, bottom = 10.dp).clickable { + expanded = !expanded + }, + ) { + TextField( + enabled = !(settings.isAutoTunnelEnabled || settings.isAlwaysOnVpnEnabled), + value = settings.defaultTunnel?.let { + TunnelConfig.from(it).name } + ?: "", + readOnly = true, + modifier = Modifier.menuAnchor(), + label = { Text(stringResource(R.string.tunnels)) }, + onValueChange = { }, + trailingIcon = { + ExposedDropdownMenuDefaults.TrailingIcon( + expanded = expanded + ) + } + ) + ExposedDropdownMenu( + expanded = expanded, + onDismissRequest = { + expanded = false + } + ) { + tunnels.forEach() { tunnel -> + DropdownMenuItem( + onClick = { + scope.launch { + viewModel.onDefaultTunnelSelected(tunnel) + } + expanded = false + }, + text = { Text(text = tunnel.name) } + ) + } + } + } + Text( + stringResource(R.string.trusted_ssid), + textAlign = TextAlign.Center, + modifier = Modifier.padding(screenPadding, bottom = 5.dp, top = 5.dp) + ) + FlowRow( + modifier = Modifier.padding(screenPadding), + horizontalArrangement = Arrangement.spacedBy(8.dp), + verticalArrangement = Arrangement.SpaceEvenly + ) { + trustedSSIDs.forEach { ssid -> + ClickableIconButton(onIconClick = { + scope.launch { + viewModel.onDeleteTrustedSSID(ssid) + } + }, text = ssid, icon = Icons.Filled.Close, enabled = !(settings.isAutoTunnelEnabled || settings.isAlwaysOnVpnEnabled)) + } + } + OutlinedTextField( + enabled = !(settings.isAutoTunnelEnabled || settings.isAlwaysOnVpnEnabled), + value = currentText, + onValueChange = { currentText = it }, + label = { Text(stringResource(R.string.add_trusted_ssid)) }, + modifier = Modifier.padding(start = screenPadding, top = 5.dp), + maxLines = 1, + keyboardOptions = KeyboardOptions( + capitalization = KeyboardCapitalization.None, + imeAction = ImeAction.Done + ), + keyboardActions = KeyboardActions( + onDone = { + saveTrustedSSID() + } + ), + trailingIcon = { + IconButton(onClick = { saveTrustedSSID() }) { + Icon( + imageVector = Icons.Outlined.Add, + contentDescription = if (currentText == "") stringResource(id = R.string.trusted_ssid_empty_description) else stringResource( + id = R.string.trusted_ssid_value_description + ), + tint = if(currentText == "") Color.Transparent else Color.Green + ) + } + }, + ) + Row( + modifier = Modifier + .fillMaxWidth() + .padding(screenPadding), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text(stringResource(R.string.tunnel_mobile_data)) + Switch( + enabled = !(settings.isAutoTunnelEnabled || settings.isAlwaysOnVpnEnabled), + checked = settings.isTunnelOnMobileDataEnabled, + onCheckedChange = { + scope.launch { + viewModel.onToggleTunnelOnMobileData() + } + } + ) + } + Row( + modifier = Modifier + .fillMaxWidth() + .padding(screenPadding), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceBetween + ) { + Text(stringResource(R.string.always_on_vpn_support)) + Switch( + enabled = !settings.isAutoTunnelEnabled, + checked = settings.isAlwaysOnVpnEnabled, + onCheckedChange = { + scope.launch { + viewModel.onToggleAlwaysOnVPN() + } + } + ) + } + } +} + + diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsViewModel.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsViewModel.kt new file mode 100644 index 0000000000..7143c1b4b6 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/settings/SettingsViewModel.kt @@ -0,0 +1,124 @@ +package net.nymtech.nymconnect.ui.screens.settings + +import android.app.Application +import android.content.Context +import android.location.LocationManager +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import net.nymtech.nymconnect.R +import net.nymtech.nymconnect.repository.Repository +import net.nymtech.nymconnect.service.foreground.ServiceManager +import net.nymtech.nymconnect.service.tunnel.model.Settings +import net.nymtech.nymconnect.service.tunnel.model.TunnelConfig +import net.nymtech.nymconnect.ui.ViewState +import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.launch +import javax.inject.Inject + + +@HiltViewModel +class SettingsViewModel @Inject constructor(private val application : Application, + private val tunnelRepo : Repository, private val settingsRepo : Repository +) : ViewModel() { + + private val _trustedSSIDs = MutableStateFlow(emptyList()) + val trustedSSIDs = _trustedSSIDs.asStateFlow() + private val _settings = MutableStateFlow(Settings()) + val settings get() = _settings.asStateFlow() + val tunnels get() = tunnelRepo.itemFlow + private val _viewState = MutableStateFlow(ViewState()) + val viewState get() = _viewState.asStateFlow() + + init { + checkLocationServicesEnabled() + viewModelScope.launch { + settingsRepo.itemFlow.collect { + val settings = it.first() + _settings.emit(settings) + _trustedSSIDs.emit(settings.trustedNetworkSSIDs.toList()) + } + } + } + + suspend fun onSaveTrustedSSID(ssid: String) { + val trimmed = ssid.trim() + if (!_settings.value.trustedNetworkSSIDs.contains(trimmed)) { + _settings.value.trustedNetworkSSIDs.add(trimmed) + settingsRepo.save(_settings.value) + } else { + showSnackBarMessage("SSID already exists.") + } + } + + suspend fun onDefaultTunnelSelected(tunnelConfig: TunnelConfig) { + settingsRepo.save(_settings.value.copy( + defaultTunnel = tunnelConfig.toString() + )) + } + + suspend fun onToggleTunnelOnMobileData() { + settingsRepo.save(_settings.value.copy( + isTunnelOnMobileDataEnabled = !_settings.value.isTunnelOnMobileDataEnabled + )) + } + + suspend fun onDeleteTrustedSSID(ssid: String) { + _settings.value.trustedNetworkSSIDs.remove(ssid) + settingsRepo.save(_settings.value) + } + + suspend fun toggleAutoTunnel() { + if(_settings.value.defaultTunnel.isNullOrEmpty() && !_settings.value.isAutoTunnelEnabled) { + showSnackBarMessage(application.getString(R.string.select_tunnel_message)) + return + } + if(_settings.value.isAutoTunnelEnabled) { + ServiceManager.stopWatcherService(application) + } else { + if(_settings.value.defaultTunnel != null) { + val defaultTunnel = _settings.value.defaultTunnel + ServiceManager.startWatcherService(application, defaultTunnel!!) + } + } + settingsRepo.save(_settings.value.copy( + isAutoTunnelEnabled = !_settings.value.isAutoTunnelEnabled + )) + } + + suspend fun showSnackBarMessage(message : String) { + _viewState.emit(_viewState.value.copy( + showSnackbarMessage = true, + snackbarMessage = message, + snackbarActionText = "Okay", + onSnackbarActionClick = { + viewModelScope.launch { + dismissSnackBar() + } + } + )) + } + + private suspend fun dismissSnackBar() { + _viewState.emit(_viewState.value.copy( + showSnackbarMessage = false + )) + } + + suspend fun onToggleAlwaysOnVPN() { + if(_settings.value.defaultTunnel != null) { + _settings.emit( + _settings.value.copy(isAlwaysOnVpnEnabled = !_settings.value.isAlwaysOnVpnEnabled) + ) + settingsRepo.save(_settings.value) + } else { + showSnackBarMessage(application.getString(R.string.select_tunnel_message)) + } + } + fun checkLocationServicesEnabled() : Boolean { + val locationManager = + application.getSystemService(Context.LOCATION_SERVICE) as LocationManager + return locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER) + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/SupportScreen.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/SupportScreen.kt new file mode 100644 index 0000000000..31fc9dbf6a --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/screens/support/SupportScreen.kt @@ -0,0 +1,83 @@ +package net.nymtech.nymconnect.ui.screens.support + +import android.content.Intent +import android.content.pm.PackageManager +import android.net.Uri +import androidx.compose.foundation.clickable +import androidx.compose.foundation.focusable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.graphics.vector.ImageVector +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.style.TextAlign +import androidx.compose.ui.text.style.TextDecoration +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import net.nymtech.nymconnect.R + +@Composable +fun SupportScreen(padding : PaddingValues, focusRequester: FocusRequester) { + + val context = LocalContext.current + + fun openWebPage(url: String) { + val webpage: Uri = Uri.parse(url) + val intent = Intent(Intent.ACTION_VIEW, webpage) + context.startActivity(intent) + } + + Column(horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Top, + modifier = Modifier + .fillMaxSize() + .verticalScroll(rememberScrollState()) + .focusable() + .padding(padding)) { + Text(stringResource(R.string.support_text), textAlign = TextAlign.Center, modifier = Modifier.padding(30.dp), fontSize = 15.sp) + Row( + modifier = Modifier + .fillMaxWidth() + .padding(14.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.SpaceEvenly + ) { + IconButton(onClick = { + openWebPage(context.resources.getString(R.string.discord_url)) + }) { + Icon(imageVector = ImageVector.vectorResource(R.drawable.discord), "Discord") + } + IconButton(modifier = Modifier.focusRequester(focusRequester),onClick = { + openWebPage(context.resources.getString(R.string.github_url)) + }) { + Icon(imageVector = ImageVector.vectorResource(R.drawable.github), "Github") + } + } + Spacer(modifier = Modifier.weight(1f)) + Text(stringResource(id = R.string.privacy_policy), style = TextStyle(textDecoration = TextDecoration.Underline), + modifier = Modifier.clickable { + openWebPage(context.resources.getString(R.string.privacy_policy_url)) + }) + Text("App version: ${net.nymtech.nymconnect.BuildConfig.VERSION_NAME}", Modifier.padding(25.dp)) + } + } \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/Color.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/Color.kt new file mode 100644 index 0000000000..3561a75512 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/Color.kt @@ -0,0 +1,17 @@ +package net.nymtech.nymconnect.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFF492532) +val virdigris = Color(0xFF5BC0BE) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) +val Pink40 = Color(0xFFFFFFFF) + +//status colors +val brickRed = Color(0xFFCE4257) +val pinkRed = Color(0xFFEF476F) +val mint = Color(0xFF52B788) diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/Theme.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/Theme.kt new file mode 100644 index 0000000000..647ad9f2ad --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/Theme.kt @@ -0,0 +1,80 @@ +package net.nymtech.nymconnect.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.SideEffect +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.toArgb +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalView +import androidx.core.view.WindowCompat + +private val DarkColorScheme = darkColorScheme( + //primary = Purple80, + primary = virdigris, + secondary = virdigris, + // secondary = PurpleGrey80, + tertiary = virdigris + //tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun WireguardAutoTunnelTheme( + //force dark theme + darkTheme : Boolean = true, + //darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + //turning off dynamic color for now + dynamicColor: Boolean = false, + content: @Composable () -> Unit +) { + + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + val view = LocalView.current + if (!view.isInEditMode) { + SideEffect { + val window = (view.context as Activity).window + WindowCompat.setDecorFitsSystemWindows(window, false) + window.statusBarColor = Color.Transparent.toArgb() + window.navigationBarColor = Color.Transparent.toArgb() + WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightStatusBars = !darkTheme + WindowCompat.getInsetsController(window, window.decorView).isAppearanceLightNavigationBars = !darkTheme + } + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/TransparentSystemBars.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/TransparentSystemBars.kt new file mode 100644 index 0000000000..6a1c35331c --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/TransparentSystemBars.kt @@ -0,0 +1,22 @@ +package net.nymtech.nymconnect.ui.theme + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.DisposableEffect +import androidx.compose.ui.graphics.Color +import com.google.accompanist.systemuicontroller.rememberSystemUiController + +@Composable +fun TransparentSystemBars() { + val systemUiController = rememberSystemUiController() + val useDarkIcons = !isSystemInDarkTheme() + + DisposableEffect(systemUiController, useDarkIcons) { + systemUiController.setSystemBarsColor( + color = Color.Transparent, + darkIcons = useDarkIcons + ) + + onDispose {} + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/Type.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/Type.kt new file mode 100644 index 0000000000..6b89a8e327 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/ui/theme/Type.kt @@ -0,0 +1,34 @@ +package net.nymtech.nymconnect.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/util/NumberUtils.kt b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/util/NumberUtils.kt new file mode 100644 index 0000000000..aa240e6eb2 --- /dev/null +++ b/nym-vpn/android/app/src/main/java/com/zaneschepke/wireguardautotunnel/util/NumberUtils.kt @@ -0,0 +1,25 @@ +package net.nymtech.nymconnect.util + +import java.math.BigDecimal +import java.text.DecimalFormat +import java.time.Duration +import java.time.Instant + +object NumberUtils { + + private const val BYTES_IN_KB = 1024L + + fun bytesToKB(bytes : Long) : BigDecimal { + return bytes.toBigDecimal().divide(BYTES_IN_KB.toBigDecimal()) + } + + fun formatDecimalTwoPlaces(bigDecimal: BigDecimal) : String { + val df = DecimalFormat("#.##") + return df.format(bigDecimal) + } + + fun getSecondsBetweenTimestampAndNow(epoch : Long) : Long { + val time = Instant.ofEpochMilli(epoch) + return Duration.between(time, Instant.now()).seconds + } +} \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/res/drawable/discord.xml b/nym-vpn/android/app/src/main/res/drawable/discord.xml new file mode 100644 index 0000000000..df43339353 --- /dev/null +++ b/nym-vpn/android/app/src/main/res/drawable/discord.xml @@ -0,0 +1,10 @@ + + + diff --git a/nym-vpn/android/app/src/main/res/drawable/github.xml b/nym-vpn/android/app/src/main/res/drawable/github.xml new file mode 100644 index 0000000000..32f8254ebe --- /dev/null +++ b/nym-vpn/android/app/src/main/res/drawable/github.xml @@ -0,0 +1,12 @@ + + + diff --git a/nym-vpn/android/app/src/main/res/drawable/ic_launcher_background.xml b/nym-vpn/android/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000000..07d5da9cbf --- /dev/null +++ b/nym-vpn/android/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/nym-vpn/android/app/src/main/res/drawable/ic_launcher_foreground.xml b/nym-vpn/android/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000000..2b068d1146 --- /dev/null +++ b/nym-vpn/android/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/res/drawable/shield.xml b/nym-vpn/android/app/src/main/res/drawable/shield.xml new file mode 100644 index 0000000000..e49a1f265d --- /dev/null +++ b/nym-vpn/android/app/src/main/res/drawable/shield.xml @@ -0,0 +1,5 @@ + + + diff --git a/nym-vpn/android/app/src/main/res/drawable/vpn_off.xml b/nym-vpn/android/app/src/main/res/drawable/vpn_off.xml new file mode 100644 index 0000000000..d33949b74b --- /dev/null +++ b/nym-vpn/android/app/src/main/res/drawable/vpn_off.xml @@ -0,0 +1,5 @@ + + + diff --git a/nym-vpn/android/app/src/main/res/drawable/vpn_on.xml b/nym-vpn/android/app/src/main/res/drawable/vpn_on.xml new file mode 100644 index 0000000000..1339fb3b8b --- /dev/null +++ b/nym-vpn/android/app/src/main/res/drawable/vpn_on.xml @@ -0,0 +1,5 @@ + + + diff --git a/nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_banner.xml b/nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_banner.xml new file mode 100644 index 0000000000..cf3108b364 --- /dev/null +++ b/nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_banner.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000000..036d09bc5f --- /dev/null +++ b/nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000000..036d09bc5f --- /dev/null +++ b/nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..52206777aa3245f61ae885e0825057c0550c2f0e GIT binary patch literal 2004 zcmV;_2P^neNk&G@2LJ$9MM6+kP&iD#2LJ#sN5ByfRfmGMZJ3%r>|F>EF#*}5s2`8% z(Y0{0{g0&l%5BfNf`6&WWd2;`|9Mu?$Q~z%SS55=LIW-C5QLl62G(t@ZEF&DcWYB6$Ocw&D5>dLftJdp za+iuQgAJhT*f#-m^Z#EbDUF;9?(XjH?(TZ-?k?-QwJhz-htqO|J!{hpU3vD)1i2tO0WS z_W^{YWTb>NveAU(cM)z?I3;*~qz(;`Uk4ZA;YM__(P>8Jgp*xPrZEHo0Lwrb1ItQazE9(}vrgvpUY|cKYSv z=T|iaByDWN<=G{O{BK}r^2(|%FGHOlkwc@mq}gYqPRheLh-~uHBvh#A#w$14lrkPm z8D_s!??{ZRP}XJg1BjYqIR#g{fSMCI1=k@pr!mUp-U2sUbFRlLrdJf)bZCmN#1_m# zY`oTGbFViLnEE5(ofSu@R`_WVi(YQoTzsHnB_r}zzV=o)nuNT$NS8~PMlQr1u))Su zsyxk&SB$yY$o87@Gx?bGC#&y{v88em;4-m^0=7oi*qw=gldtLCGT~q1P5Adx5=o0~ zFxktV%v|?7-9u)4+I~x(?Ix?!t*0^~au5LN22Kfpf}#!sz0TGwc)c^cW|H5G|DOr| z^T_OvyW-)r9c))fwZ)EiTV@F0#kfMFOydy$4+0KI#+T!xlW5`uD3n>0qU4msjKs{8 zgv`(as6W;5CjNcyK$Lcg3`>+wdiBCH@ESRcoQ=>mch4%Yqg~P=+u6VN_KQfR7;)iGAGl1pt3O# zr;w@x29^>$4i+Ajg|0SU)zUMx7D|W6Sl)bJkxkfmZAOe3QLgqjUzu!#ZUv;6Kn!aM zZX1iB!awbM;#I7?&b_5#m(8nFUsb4P=I2DU8`WO3Jx=-RtKQI29GgYo5FC_xec8(@ zs7T8EFy4rU6V(%cUO8Sd(QO6RCV!g$dfn6kI+W&kkm}LJj#!Unh(v*1rWpV0!f6%(YFW~Me9YEim&!e2RiUTPsFrZrIhtH8{qmt z$No}8v%Y{o2Ljm;mN{AJz=Z$ri9GgFM7CR@`Zix~#ZLP+881aN;|r)}6DR+U7KV>j zI3(2yLc6MJDThA%`s?R39jg(ICt6qJ`lwwtTnm9}i=!B)*0H~5dda>M{J%LKv*(-- zJI~!dCnwjNZU~m0u*krHlmRqo`4XSaEBz#1cQj^bS@H+5!DyE+Cq;I zk^b z7V9d1HyiD%{uYrnb_cfmQE|@vH!GU?@Gq4J9yQtbWf75;*ESK50JysoJU`H-w=UF< z99IAg+blREkC}I~zE-HOvN}nCFKixGdVV-(;j0x5^)WRI1iMLiT(fLCbk$_v>GR=u zzZt*y#{bWF#r#^S^s1EJrYntl`vEIdpO$3#_c0Jl*(CX;rKOz! z)ss7bk8cs5ky)PC-XQ41fHMseIP011am9z^pAS$S@_0yBP4V@_r{u^E{jHMeu|a=- zC_W}9)taq8;no!own8Q1b8>b6JMS5IqVxtNFwI9!l5M_)*BHHa?C(SBoXRP76H?1S z%(0MZNMWi{n*1~srlz)okMsdh00-Pk?)_>Mxaybr0)ln+(KVn-# zo@nuHr~Uu~ctCb)>I-vN*3+EFr6eThOh_}*XrviwBx$4>X*AM|G}`yg_21(az-nLy mIKTlyAOhmfZ|?vb;B$y7K*FoQF<@JrzkPnvRMMS zIKW3lL`O9ACZIa#y-m>)0nt;1V{-qf~j+qR8w+h$Jy-D=y`Pf8)U zyF=uXt-HIsySx8w+e{|Zg--Ng$!2=k6Cg|czj)lR zLg1yc{Q2z=299#v0gzht4I7=p3wuoxc#%@*LuOk3WCK0runKCu20faBaJ!Ol(T*hK zhHQEpl=~mlc@9YBEuTNW5CuvC8UTDIIV3~1eKFhxNnm99`px98Ooac^7$)bV23uop zpaw-;u?PSF@t8wXx5QIG3V|=6js;4xL?3hv_)nvsDpg!@7y=;JO%<_7yaX(fz#mwK zI)|bFszd;m0Gu=0M}j6HpaU1mqSZMZ1%gKxQjm>kI}F$&N#F^PnI+QoTOqPJfKpo^ z7dS4`)>D*uN(|&~u&c_Ff0;MBlI5cm7A;n<(|57?dQJ2wEj*FH!6g>Cu}LPfkO~BL4=zKF%_gEK!u+SZ%OX5npUh< zCCiDG0}WeR)&&`J&}U$o(bWH|<5jTkX)FiloR<$DxuqOaFV(y~nJ<4)rC<1MTKV2@VWw3Lv-&(q+T~8sRXgL$rPUbpU|W zUU9@iFnLv~(Ega~|C+7%!ufuWG8-eX6r>Txya<;*NpRs{$bx0B!(cT92-L)xEZele z&xORrJ`S6vLb%g955kl76bQ~NK4K|zm-zr^eDYZ3bFS-zyy+3rc-j&TI6s~>BRzHMS zCJ^iy*%ZV8T#3Uku)0)S%khSYzX1Sr94d%dzHdw%s~1qFW;Ll?gpVc>zIc)Ww9jSQ z5wv?!5U9%{j$pax12NC>2Z&`iK8TBc9@#*jb~3?+l07X3SgOm^I3&RLIBXk*h)#7P z1xI)Xu}5!VFzrid6s}rj%Ug!8B7YUBb|h{a6F_cvnE=OeG?;0KE8cy8T4H-37TFyP z+B7lL7nHQX!5~CK@L)qCAdTXDEnyZ9SUJ^6 znm-7iwWSecL4+=~a-VW|j_1)AC{eL2Ndzc3DNx1HhVmj!j@j{RmNpI3qy6Rj!5Ztx z$eF`?=Xn5liSUsy&|g(*u#WLZZ{{kb?h{}mkJseJYA9pcD4jPzjW)C8SZO;_mVG&B zg;&P@4`sOWxVe`V#i~|&6w^<9blS=nI}R3SPyhVXsn*?8hzHM)nl6A47vJ=oHEX1< zxzMbe3c&BQ(whT>VJ3K_1)$z};>t{hv5LA6rsYqzQXXWhX3=~q1YqA#Xyw-jA;bWW zazG<_DDiXQ7f{(`033!oNEif z+q7B>jWF;5VB9R;1S;Z~`~O<}{n&n8TEm$^7^6;#1sX$tOi6!2r5M<2kB`mLQg7R) zZ4fodiYB0e-4u^1Z?jDY1~xYOeKTIFVqJp^OP4O$#|xT@SolOmL`qQy3)ikee4|Wt zT&=YtO@pbHoIG+?zi@(&fx1t;s=U=vY^jFQiQ5kFQ{XGZ0ZN+2Qw_wbh=E_G9=^GN zFHu>ZA^-rcT>klxq}5mxqt$Wo>|aqIx&sN|(CqBM68M$NyFwl8qV)8ozO`7imz0!_ zL#_RAX*JS{caAz^t?fu_Io?7di6}kjo4LAC9f_FXCV)WJXW+^M$jN*thz3f;yDH)k zp%7qcLYim@9&AVy@M=m5qkrUbQ>E%>KWX~#okT(P5D%{bJ{UA5p(qV$!XTQ8;R_-7 zkpbG-#7Cltw?U-oF3K3WsvoyZ&1$8GJcjb{YVkAJ!8p7zD*8)>!%M>H9zY5hMXQ%> z0E$MCcshLv^X)N&S>h2E0N^m*mrw*9OME5!ON9$H#UpJ1K!h#67vbcz{K+Q%zQXjA zrw@uQ3)(o|2LSwVR3XdW4Z-dU#p4OkVdzk{q! zkbLyzM)yGuEJ3_JeH}_*OK@F_^5p<<_N3<~Otb{}QAk_0*vzsZ?+ z!UoKyyC`Y=S4MtuQha}TJm!)nm1hMJz@0PV|3v#A<1xP^+weO0YCZk$089&G~JYgklo@g?P+P zf)F=iFo5i(qZ0*^1Rj@3I357IYqGqzeRo0fo2mNYlaNd)^!xHT_7Dl1xKzUO=yiEq z)3FBxN(X&IETQ?{-*)G9?CY4#Xr_X%{fZC__8jjX%7ySux)ySux)&vAD@ zV@Hbn&+q^LPakNu@m4?sHX%h2QUoQCS~MZq4~GWqWY7fHwU*HXF=Td#++8BgDPfUkX_~dnZI)F4z(ZQP5IIpC}JRBog8I7x41u`=b2k&2Wm*XQB3Fpa@=LB&BNAoxP**k$=hZr*5UA!;0p!<62w@(r z>%z)t9!~d(d~YF~6XwD6z_R1IP$9YdN=^vy|0TIf)TdB65)g3}j?)|_^KiL2P5v@p z+LLuI)2-DAuaU2a1a>&R99bFXh0cV-L}TB_u(mARvv;U6(^S49@=L(LL8rpx{gY1! z!D(;O%a~Rx5!4P|*Wko1Mb;+hPvk3Hh_RcSAS!zvp&HS=0?Ymsg8YPszltyHd&Gxh?fuSow$W71elw?BOi2ae2rr1yMf8&#}t)0h>K+;3+Vx zu1d3=>|&!mCBjQWzhp?1=ft_&bjMq9wgrtkhIk0T@Sy1BkP-ku;Sk!RwM#C|SJ596 z?kyp{66E&_{QCv{`9gmr@=Fq3?Vsy^*x|3Y$tRv48B-NKIYK6_59}IW3pRh)0D#Im zQK!0^c%@gXd6h0@y}^n*MJXkM6_rh*PGfaxueROQrl;C>RnL|(t5V`JYt|-DJ1p}{ zAgYncIqgY(=Hap<>zlmprvcjo0FG5^L8MD~OTNuwf$ z1@!ZFQYq)ZZZf(#dKW1l{T;0{C~8!)HNW=ZBW&<~he?(Vvh|);65l*xMtRxVp9gII zu!ASZ!NG$cAf|LvaOXfR5`ZtR2!W*5jpB-F39-S8eq#b(s zZNBtSKo(a0K47!Q4Wyik$?IN1H_L|IB#XqayUf^j=2cFf(1v|61}hkt{}RBRpmZYu zW{P%(g!MiGi~J9er7)J^yrx11(XGiRW!>MM)lN2If&?Q$I6*oq3>P765S_Ktl6{>z zD)Yf4yiT^g?cQ1nzy)Af6d0u(1(-=V=nz`=)uF^Ihq$^=LI#z!tO?NXV=Rm`XU95~@u#`9O$*L>bAp7M|vFLGmW9 zg$BYHqz<=22o2}er+Q03no_EX8KHOv1- zW9Ri%h_C6A>>Y;?l5So$@4e_uUf8+x;?Rtnw@I zl7no0-FkkMM2+YnQ;sD04QPyORh|=^%083X7ms05mre$yO4s>g+kY7o9xl#uJs@&TX=#+wC9nGigpX?Mc4Oa5$L`H|9fV+}l0G)dvt`^z(QyS@xXBg_WC@vx5vOh4Is+ zU>?k8DYV#1bMr}myp$^kSyT!L5xOP+V#&3$lndK@={T9{U8JFQjch}d#(0Q|wIXLm zJ#m&0M+0kQn*EjWpZP+3rN2z1yL2S}X)M_uQ`tWgjkm2;Y;^2&>0As78NH0Pk458-41pEt+teUyo%Y7e) zj9Ft11Z3}|H=#Z|U4XTwIWW!cP_D#0-_F1ppKHmlTX1TI&?DUYM>&c7i&C>~sEp`^ z+uDZ`Jz9#;gq*&4R;uPY88?v889e|~RfY38IHNz*#(+hEu_00X~lM;de3K6D$?vai)( z=S~KMoJQnKAU3*P@wIeL0ZgbgI~pGKD5Iv2ygDx)n3+&M5!pukI~dl5&B@Oj@~mi_*Dv zz_>IHthCUEZN89iYZJ>XG*R3+t*x_#`1<+|>|o$7094bAp}cD`mX~HaRzj2s{BVq> zjfSXBwtD;zABIp|#pHEW(aZC~3+;`o5TVD81SRC|5Mf6#@hspwEaU2i8CP?%u?@d9RxB`CYG+ zquOpLTmy`+8%8^U7Z*UhmENp=aWat5WZ#?jSe3~Z-1J8y&u@gWytXR;zt2H?CBX-f zNvb3>5l17EIF|~bbDxN^6|O@Cp8l#rbZVUt0>}eQGu*0Dtr3&S8-X3o=nURfbMrYYD70Svjk9UgL|4QW`andy5r59TPM0b&DAz| zY*(78(WOFg5eCQswBtr%hKCnN^hEt!+tvHd4W6Lr;?rU(x!QAm-plOL`F9bZ*QsKX z%M?>r`%fmS*8~4ti~OKoCz{L??%S`^i2bGbw>z)&t24D!tTw|jK5H}FG=yRnh$2}% zimJv!$#CPWdjZfnJkJ)CQD`jhO?iG}-;dtf z^0;?T8TqBwb40}}@N`=5@qgbx8=!Gf0}LBrI?@KWR(Q_+f208>hhKEj?Zg>an7&^#H7odksD^s;#igNw!_LgO+Bm(U0q2Sb(#VA!^8 z*f4?E$#%~knA-pV$R@UJ8&{-j-}48?Ro3WEfZY85*Ev}PcXxNEba!`mcXxL=iTuyq zWx3ezpGl~$TG)Vx{surdVGKGJ zaCgd7{}#Da5N+EoB-Q_~m6U?Y%S)+yY}>YN+eTFx3|K^^|1UQEp8#x10wzDA9`g~9 zBS7~Y4hS-PJodWEpI?AyI2cNFz;-WtQNR2DfoF-1WdA|3P6;qAf>A_|Ci|56s@KMH znqh)~6VI5tRQ6^S@m?A4ePSy-r_Ed@a}8u->m2(sO1?Vh|1%idMy14?r8VulFj|=Evn!{(U1B2h;Ur-y28J91 zV9Jmfm3px?Di_AcFfo?07&%IeLjxz`0-k2L6dRp@#K9stBNFI+<|+V;m>fpM-)%@y znCSiLJr=R3{VtQ30l(;q_5mJ2>Gavd2_uv1?^EaY=yL5VpSuICi-i;6D6u-LsA>d- zi#33&ZlSLy3J}qxemNB!#~2_8f+Zr6*_QF66G0S3;<6-Efe%x*{D)7?N1~CPlG~lf zS?k8*@r-SnY?+x+-OB?O3sfGVfCZ6NH-Umn+qIr(X1}0vuuA|mIx?}#k-em$&>$9p zlwnkCDDq(niW^(-%S2zHv~dIgvKr<7GY=_kw-lYm;>-@21zNog+HYL;*W zFRS00_@b73XN~Gr7+#nJA`d|AV3Wv!aKI7LZEa02v*m&F<3Kn>>#}#LAc76C8YYe? zYw-b4w%kK!#*2&vG8(VA`nOdP7q6(@%}BqzlE#_(vcP$)C<|NxvuYn=YCfGK7Y*3u0b0!;1?on e(REB;y+!YEab!Dz5j4T6Z;y`LSMs6iS8Pg*JY-e? literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..106e0e13cc5996f9e412a6277c365a55550b330d GIT binary patch literal 1926 zcmV;12YL8XNk&F~2LJ$9MM6+kP&iC+2LJ#sYrq;1HPN;9|Mca|eZ;nt+O}=mw(T6- z=FBnvzwa-;fn1OFckexG?S0zhH|S3HX`|8=FJii^wPUu^#kmICcDk%oPAYY?(wViZ zL6vIyu(QqDMrYeem7H$6X_MBr*`_pZVpgssg>2il)3!=}vVUWCm?K-Z&OTC@p}ow^ z%*;$r%pkdqBuSFII;#X9Ay+8~ZQHi7c`|3)wr$(C-A#a+ ze1MX4A@*7zUGomf$xZN?0Ku1WqTgBa3c<-na3h`RWi}EF1bZfQe}&}@0;x&x3?FuH zRuK&dcIEVwY&&Bm|4R^WyO>3SO$nWR1j`8i11^-iQve8_3r@$0yq_SOA#w(icH{Ym zrj=^z6Racn0{}S+Pp_aQxF%R%(My6EnWVHZDQ77nw*Z0tKx@r~mq$|f+El2_>TBr8_=TmTU5DT$@t!9*@I9f239cRr0P|Uj*lP~HL1jq52lUn;!{)msrILQ54~sK6Y9(CT?Gyu9*oaITovtP1i&IVYxTxX8sDO6H%$?3W4z&emFRS$Ce^^WzM7^MlVuWk|8TCCQ{Oi z8F6jm>%`U=Az3|-UmU>&OA$OmOotw)BfMM@<%%p5S*>2WV+5?2Do2c9)|mZa4wdqO zOo^`#fcQp5l#3(SVW~Bcrt$2oG8>%`S7RW#JSEY!imKM&Sfl8rm(s7{4#$wkB4$>M zhg-P{AYGPU0D!nUk(J^ImRL$+4}yO+BL;}6Rdf}d!H-{R`tztN`*5nxK03Sok*fjl zj*9?F`sWJ3u6uF><18h(D~rl7N22P?!>Rt?qqd(n$7%b~k)zl!2MpZAg$1MvUIMV^ zuAEfc+)@NHb^L<*-#}`gT7TV~)}9_|y%NlzCoa`w9!~emi@RIHRA_tkN;UvRLB_}vw4`vmRb9-hK@!R#)>Eh#gUu7L=5A zbQaZnxw`)kCwx&FwEFCD`n+&q5}SmT3cxQ(nw*rZgu;rT?!ukcQUnjpC5+2?B}c>b zcJbo0|KNiuvmFeQ+C~;5SjG9}%0Se-oNE6+zz%%!;;`g_j58x2*syTZ$7f zQrTiff_vr+2Coa)ZR92?5{BUY1mYWK4@#=-%@vUhC)QeXR|rz z?=6O4va-o(|6^i#bvAi-eyzc?LtY~_RIl(0RSGa^T(sM zUyp^W7>HaH^ob2uw)qpm2~B2#k6++tiKuYPW=W%pomSMm21z4i8IkjXKEa(dk#PG^ z!lWF*UjSJt!!(x833owzi6CH5a2hH*6)+1xil&3*>kgewm@yp$FmQ~r)y!d{4+HQG z_*s|?rrpJBq~_Yor$i64SCTS|rMzSO1{uC{JL%UJA%n|1^f{4yFJo@6jJwyg=|#PzotK9*6$q*a`eBn=o!R z&~7VfYAbu*o7ih^Yvvm_yEFvuKI*1{jatJELsbvSmkW(c$cMFt83me`ViC z|D%aDD-tV3u=2_)CrAcvuW#@rVS6b%U+G!s=Mo-nf#9pqX{zk~{HyeG6rOJVe5SH{ z(MyD+-KevSo0a{7lTF!wMS_{@XilTll$ebK7s@0cPn4t$!583d7pIQOD_uxYNqbh( MZk0*0tH~@60R0}G`2YX_ literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..c388f6dae5a66dd7133c1c43af5f493e7a735579 GIT binary patch literal 2242 zcmV;z2tD^wNk&Gx2mkZJ3xp?HvjcF#*l+iB`GU z{x_2H$9uQCvpXZ<2?=R}R_MQiyBld|JNP%iLwc7}1QAvIo{e$wnUoIh3Lv}`8`DBT14|`|@XYBo4*t zBX%{Y~f&bDoOkFCv|_2QVBr3|--%yKfVfCjj(4{L%BsNgh! zM-=m>hnx-^I*lZ-{|ApikZt1+@>?!d{mcB*U;r#xt}Gh9FJnHm*|rc)B}|BR(bbvt&dEKg+-jz{};aX!q7 zXx~<8{RxPd5o#!c-b1G$N%(rKmasjSOpq*PtJ&|VvhT<7It$`h8hK9F^zgnz6zT6w zPjk1bt;j2b2Md&ml}ssEIJ`5X(X6DuS#ds&;Q0SL1rJy3j}4-Jg`Byf7CMTA+KxU5 z3Sv}cbQzR-ebQz`di9Rcm7xg(01O0-3IJfk=*fP5Hhe5}7e4@O2pO*pbqH!RptX3GgOz|9K&{7Q+)ytVt!8v5;bOtb z#^68zfW)LqmWD|H@K(yqV5X4CfRRA17689QrM@$u$txVCv2AI*4GBQ?=LI1ahF>xj zp&SBZ000-N%4<*b?-T9k6h3$YVvt<*l1vmn3J@yS3V>U_622Ocz~5etTTb^>7)$dK za>{Nk0FWzqs6+780ayU-MR##=W6MIhRY2>~#v zuUxLQvtVz?r?~Iu0N+gFsUx*@SZx6BlRa7YegVI01o#Wg4Wv+uD89D{Kn=bba_#Iy z?SvKO$GkHGz-NK|HqUGUns9w zB@WpU_sz)Oc61DCj(tQeCIvwV3KRHcq6i(HACZ2KSjM(wp5n~G~w>TnFW9bb7B|sc}O5J`C|wee+{alSf8eh0?>2x;=kMdgCoJC*+>wr`i90r z079S#KpU=jZ->P4IYz+Rit~>0VGP1lUwPJIo=hpQq3S#+O=hI}W2S$m2v zKIPY!bFl!xBx;K|KbbUhTIQP1;bd6_$9d9tu|Ci6+JK2;CJR?T^F%sw!!dy(xQ+x0xlR`sgv5Bk^Ec}qq=68wHoPpjghIlm)g+R@=N5s^ zj%~wJfi61ZFD&>hFarP~xLRNd)CevvAbpwn4;0D#H))1t4a*$!7)V8Gp?QDj{DgiT znPcE^7NN9CWx~OQk^+z^HID@h2}H<^ZYZk5mu@r^p@+s22p-E@H6D^at<$#@9BRAN z7MvWYNbo{9h&36nALvTwteS5&{EiWX{yNoVQ{rb^91J*<@OJQ9%1_r#(c)duM zpFcV$NR+48mM5EFQD3?wTgnG>D33XidBGqktqQa-0EK}ClSHnwWw*8_@@tZbAmGUl z%N#ZYhG#XUrV5oL&o;O@1gYtub8ck5S|pCDNwcQytJQtd2%@|hPjBcKYyNlOn5K>11Zgg(2u9@w>uHn;ifq#+@)JfE(1i>HKQptvuc&2?3Aj}g zO-#X@rZ7oW`!O`t#2|e?(ZsFV)gI+LPQEw-lVF~+>I+Mo0=Q9AxB(!&p0yeX76+~4 zNIWhR1SG2|v)nt}63t`Us`{zbHTEsJO=jB7sjZ9SgsVRrR4zhyKz9x(M?2 z%+|9nKdjkJFdMw|xWqq~TLju*U(X2GjE2XkQ_t1Q?)CHyZn|Y-E)mz53mp04Ze1df Q3Dna|FWs`0M)6J<0KA+ky8r+H literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_banner.png b/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_banner.png new file mode 100644 index 0000000000000000000000000000000000000000..fbd39f501dd7a23fb706d9c597bdec9b3c511e5e GIT binary patch literal 3578 zcmeH~{Xf(D8^=GgQaN&pa(CGIra7EwavNhh?kVO_2^pu3a+}EQhiyuyzN;9yYn$eF z?mDQD+ifI9Vwjs#+Em7{Y>5#wzRu(O=!fs)@%;2nXjI*n4HQxAYc5; zNr#gV2hty^2eXTJ+*Nj~?XGY!8GD#j^^|$&=|#Iw>RmOxz2->+R`Ay?h`RRU%pd;3 z2yL)=t;UGXyU|PT9Pir-8ahDW(9w=PK;TXpNZ_G=?Eh%60lyDQ#e*gQo&fACd_r|N zx3PHU8J{KJFPrh#?m(Mv775m`DD2JVAgCX{z+5!Vk1eYM_k~ z1P+p-^vyB{kz^|MSF*x$FSTJ;matMn(2649#Oz}@QxJP zt4leiy%Y_rtAA+?Ut3o4N%)+ivA9;W)BtL?zmw-r>?fp|hz!|4(^`#Fc$r?6oNZaFAJxA z%_nE_ZGQ6M_83M;&h@UCrPi@xoBDqfznv!p4HLbDu}X0Z8F~v&RNj1$o@hRs$i&H4 z$8!e?>_iIf?_Jk{b?tUiSRVC_#-oM=5(SyN$4RkuKShgIvFe!I5vXvab?Uw!`VuMW zQ-yw0tlc5&Huym_l3Jx}j`?0vyLmTjh!@~fO<46Uy~{Ca$MF4zYd_xjSy{FdzK>Zg5O&a0v| za=YbSwj1Yt*m7_r_EO1rr(B{0L#aQAAE_K(Dv_-qcUT@6VVbVCQa9E|2iLy{1mB99 zFS}ysIOG&3+53K3k(;Ls$96$6y4N?w)rcwtIDDknI@UHCRgk?upgOJX+&Gmyyq@se zsy{Jy3Jk`mb#;9sDQ9e1}?NRkLVM%xI~(0m)O-Kj>%H%Ug#P%{g1SKu=n$ zh#X{3;I6PNk`(;&E|#ItZRd^3P>R(k!d?N^5p&^9BKld}!ZiUDca5P8wfylO!u<|+ z+@pxRz7#J#K&shb1Pt7)8noiT3YQ$y)s%>4q3@b{j0^}`&TLU*=^8ekS6@h4nY0xw z&IytY6h*6lc1nyv@EWnBSXBLyT>W2=_IkV$$E9zmLtQszIt&^Aldjsz*~~%kWA8&Wj~;h9(I=SeQ7B3SbncWY7W&3b`JT=&0i`>i#Eh0d zAZ6~~`=+e`7cJ)yqhtZDpOkrBiB<(sc6d7TX70?x5OrGFgn7{XtAkfJKaY&`Skcb; zmiKe(j~lr;1zWn|q9Eg2#k+sp3^)zBCRChcLMj=+d{CH!h$g`HgrVyDK3>-p{vK+* zTjta1B=SnoQb!M$KfNm8?3>xcLvwl&!H$)7RU= z#aD`Aw=}m&qggc%Ypa)Og3WG9P*U8lvr|Fnc5&1+-THX#c!DE($dmU z)j%X>!{Ze)Ky!`p^wU^cPcm)#Sr>@6*{)L9T15n}LNosu3 zB5t=okmQ81v`kof;RDAu`a^z#xJM4MEl46xY&?jkpyQu+`umPAFXMj)waZ}JozF>4 z^2F5oRketkzV_4K!8(VBZAC%4q=rgok7f%$?BUu!XoR!20HUud+`vh0^ zvq7+LtU78#gt>;bf+JGaDXBNuZh>3P43sfQPyb%*{2Wz2ZGcuL{(YZBU_M86Q?ZCr zpHGh@$mdqggV-&`i}sF`kfYwN3yYV8caDIdw2SZk$8v+B2dZ!%olxYu>eV806FFO) zm{ctJIjydiRiLtg+{u?KXR-qTe)5)ou=Q3LAPpHJFb^K=daX#$1$5+$Wkxi`U`nSn zBT2jQMZl^nv9Z@TPJH+NTRQBEY?Zlv8rmI|Fe<>O3fM{|(x8vK1~q&x=jPtd)p)g$ zico{WiV|Bi+HDHpCs0BCy746;oV-J#Lc$hik2|590p!;BPS31Kv}08q`cfru(-g}W z{-89JXXH#JcWk;vh#Me=77zCn4lhY;i`GvmUW~EVQhDCctzY8(;EZq+76Wsd%IV7t z`ndDS%wI!;@0M|2P>+PAWYD6(F_xIxqDjM-vW5a{O~AedS$`>j;othVln@6 z8TXQPmv++yD~mh(S`d9a3KCXHHorAStSC6_O^q@Pvkw#S}I-PMY+KBzw7q`4IOK1Dwj4nItc`^ZUd#1TleYr z#_(mqm1J?y>-q%2zGGQ)J3TMemhT?bip<-%eY?lX+O?)YO-TwK(eaWwV@%&Tto%5W zJa%f}4TbzD9luWC7QjGZekamZcu4;8*N-qFydJ?(?PA4>sg^IzI?ei-5}&e66m zV`v?J7)h&hJU4oo!ZLu(#r7>gPy01_>?P&82ueOX4=*}Cn7T6X9mXH9BQyh5l@Zq7 zMqj(37RoI`@3~5&O@H*6&!uw-Gn-%SW(6{;q|>`R2tUqO8er?ogcF+0pSGu=nGHst zD7WI$Id#W#>pjH;;`pGS6Cdz)^m|}4QAf67d4AUxWSnk4$wwJr5&|5*|F6d|h<4 za)CaDocBD-Z9A4VL2#TAm{t&@j%mndsO}Dg(?+VRRv+jE^nM7SmOl1!twBfabuY-y zms)SX$MOu14p4o819CF=i^-j!T;6-goph^FmzwFW6uUV9y<3rRWK@3qz@e+RzT3S*$`ecdIxbhCG3SeWg_Mnr2pGKlVl| z5pezvat#2nlRd}rQGQ7P{5G(|@ZLZ6KN<*Z?w_Nc*7Ix2-~Q79E)MSYHMW5_{{wdT BaRvYY literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_banner_foreground.png b/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_banner_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..634417a64034f28adeff6c7c3c5b29d0a2fb2908 GIT binary patch literal 3770 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 O>pytM>i)0$zdmieM{+&@ literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..c89a4abd0e7daace668cc1a0b61de43fff99bf6e GIT binary patch literal 5030 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 literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..bf191eb8171c41c8f46e66be48b647099254f843 GIT binary patch literal 4246 zcmV;H5NYpHNk&GF5C8yIMM6+kP&iD25C8x#kH8}kRfpQPZ5aFix1C<*h?oGDBf$@C z;NR31$J({_f4$}8M&j=7?(X9=ad&qgx8v^ae&)zNeslld@Auz3`R&LhOci|U>2NNA zQ{gZj?o5Sru9db{Wi9W%3#UtkOqbjMZX1iIB0Ub3vu_|J7CCDj>U7uzc&Y8FsB}8y zis2;Wn8ey@^rZC z6|iy%xWui-sobG*sis6Kr?+b3+PT9X+~u5V7G)Moq5yzqYTftUVam;|8D~zbYumPM z+w3W9+qTK-{|7gb`ac13;{TUj<@eaP?0ZgF{434L+&|U!pNWlFVC!CsuNXQrvB9E% z>Xe8;0SZvEcKCQg5D^iSuch2UMl59Jl<#@q`Tz-=iQ6Fn7pS0*kSF45ppJ-tiGsDK zrbR?dq(ek>M8$Q00Yu!Hw_12E7`AO2IYqg>2T~+Sj^un;S46FTo<0^w;NV!>cFY;u zwr$&5f<4t#o+K-9s$?%YDW?xh+v%Mj-vsbcY5^>O1Mr^jq=5wf364p0zBGu>%!fd! zx+zQlRa^eA8jnBTzmLr9H-u$ht*)v)RX3_WRsE~_^Z0X|IQ#0k&$a<9*O*pyrV5bx zsm2UjZI)}MVN5llsY*l@N?u|QZ-KS={T*?JNuo^`2U{>2Z6VMWv;`V7Dgd+8G zw%}q^^<^H=^1zhyJ8j+8)-R5;@7k*cQKJ$yrG%1C;TRxl2s7_G`}C9(N<2kF4Iw~I zKY1uhT;m;pq$B<0r6_St9997onj&v1GlSblf&g5v7TU=+CGVGExE&(Z{!$^%_eKBs(bAvUWA=KW&Y)%J`Z3PRpP(!VHk; zOQRb$T0(%4IuXslX)Oh>~|GUQ|8a8Ma5VBIIS(FM^WXp8eSkqt0ZO`%;s0CzSFMu zzAJj2a$a8fZ&UHxRP!)(U3A)=YHy}=dNMIW7e%^eF@a zP?xeq&-4R5HZlP<~bY3 zlBnRpBC;4USR+bit|-|kiDyTO+(pKZYIu-{h?dq}+E*lmBP4HVp4_3lzC7*7m({pX zfiQs|T)|sC9cM!{WT9H02Pq<=YA>HxAtJsfCxRafOV`7p=E2qwRc#c1>eA1YA}%iO zm%mJpbDGBe%^BAi(iqklv2}g(8QUidZNFY51p6e`F$mAWCY}i;r(dEC2 zV3W``>GXnN&I`SaA+{I~)SZtdQ@ALlmoPz=pS8MF#eq0hXJZvBc+T?u7zoyJmqQ5R z=r=eo!>Cm}4-cS?g_K4v7PhwLQUTQQx*SPCs6>V&emMklZO$Pj;W7Q@W{?1ibK!SN zmI#4ud(((BX^+(a6d%d3BhHw5x1It}&c~!TN%fSwkL=h_4)wuU5(_Zh@(ELw7&;X^G;c$T#HrQ4)vYf#6E%ric?0y0SzLq zl_BF`@}cihWn5fNisS}qO58@7jbu5g81+C`}d@|&T$WFYv`uI~!8 z7?l=RiVvm!jRYW-nQ4~=*kmFS3(g6UYPXR-p(&zkR)V!c>*~75Y%BM(Bmy=j7S=_o z;6sY>0h|I^o+C~*CqSy*iY4KV0V;Z%APa^;-EawA_?xdi{^H_(sgK%(ziEQ+VSs!6 z6eos}hHgljuSXGp!H{a%>?}~kq%CMgPq+-h-5|ZUZW7CG#gEa4A-lPq`5U4hI#xr? ziK&#bxOO4fv3*V2HmiCZPxal9TVE)k;@9>pK#S6><8lC+ zU2obzaZ`x8YO3Al#iwp5i>`)K0~0Jl!{qw~kbJ*skrJo%p%C?n)$&5^SXCAohEfBS zKM%`C03O89@2f;PR8{Z-Ivq4_34@KP@lfs=M=ia)b{=X=5=^SE=?cG?UI1xpvX_@xnK zUK2!9ls5Iv*M_-Ie(l|sMn>VXz5D>_(`zTRFInEl z@MSFPrVvAx0FF(m@O=Uu5J#ScHaKC$y*!5j5!;l~{w|Q^PaC){&_+<;67E8ZNZ=)0tu|Pd% zO@Siou&;#z=z%r_AI4ttGfjIf-aKU(!qROPw;gBAlRWv!Pu3?cRrz<~ZKR5zp7W+{ z{S)Da3yGQ}LCd1N4Dbeu4I#h~jc^r2L~W*&&I~A`iLFLVxmTj5NSL1GOl5x!f6Drv zVF}drEhFMbmd$~fy)Oz;)PatKmFq`E)@IjB%^!H3QWiT-vr{dt)RBKjd-p8~vl>9M z_<5H5`G7;^d`+S(M2;5%)JDrj%gi;G1xJ=NEdNyVNWGtKOew!(l-2^ZFLRW?8YD(8w$4fSH!k`x`NaGr3Pv|A;eA`$?Kj8icDX&$&wedz+7+rN-MXAZFx+_*F{%nYBv$>)Qwz8yl&c zG?AZ1_Oy<&ey#;?KltE@yLPOYUW-g19IBql+gB;#A!&CC_yr%jCB*{MAti|z#B{!6wfylThW_F}59hT`Amg-Ehy`nzzjq|7|H> zcnbfZScs`C3Y%g&;~*kB5g5lUOiB@E@+@M>`n>X(XJI&o` zaym!p(**I#0vq$Pxf`N^h;}s>0=WSVp0osjh^nRkH`iSGCoEbxKp;JVCkN%egL+a5 zh?AWgt0J2JWw|y1L5AseyJ9|Cn4RQreH-xmFK#>4a?ls66b?XZ`1VeyCCoC=k zlt-o~&W(cWji73wC z+AXf0bT9fgQJ<$7XLZaINB|F3fE-w)t40!gKXEU0J#L322T3o zB*xwU@_>koG;mTHkW-+p=d33a^Q<_32Bl+Q4R@^uxdl+o!#Gz$MD93$7L)eaBy^+s z1C_kKuPNDb#%!xU4+3%yj(IpGi-%?HYpn*k2SxTb1kI{BRtw#DE`esffwqJpI-JUL zL3aZ<{(=rw5plX?2UQ5VD*#mdI%~W584sq0?htUTJr{v)C%?MAJwBzLd`)^v2_>#c z9dYzk)fYX#5{gA({Q!Kl2eNAWXaZUSQ`GBD7^1j-01lu6{K|G=stMDg5?;>d0U#JS z4e&v46||xfjEN~H$n31Q;EkaHz;*yGT#V&;f2L9pCC%l+dV#gRi$p^RF9D#;U~u33 zp`&R^36joa{(7h*1{i<>Fy)-pOUvVNaEHKPJYFslWX$&L{3O=EE@}aKz@By{g?cFy zEE^J+e-@h8l(YQhZ!2=FQNjrz0W5%Xo1$s6Q{ZVKKT7#iO!%tD|Gxb?U#DrayG^mn zFNc#*bg=6H96-JaIJU#H9ll-2?K9=QXX>86&s6ShhktQl^Z%&hSgQc|XavXr1FQpZ zZ7dSFv2pJG#ZhEM4~vZe79d;#w163~E_nX6*}F?G<{~SsTkKT2Y1)hx+b2%-Q8K= zji_3|WfiwmMMQNml1~-x?(PojyAkdV6C*#~fV*{VhE0TK?t1c(6kE;QVheG1cmq2c z;SU-;O#LF9gJe{#ML4}K5$>EKa|?+)JyrV#aCfMpU~AjqKuT|NHZdERuwo}={NMZi zrMN0-+qP}ncK1+jBuSDaSwvBrE^jJc#RJ?B&Y72LzKhn3#~Gjt0B0Dyr_ zN+m%(I||bhG#S&)qoYKL$-pNq2EHgF2|YM_xF&%Zx(0L^y2OK{5?w%_fxikRug69u zYB2Bz09-)DsEWs{xhw!+=xrrRL=TOE)MU(00D!F1m0~rpr{#KN0GO?zFp5}1Ky0C1%WC8g1AoDAm4>KzK|TWj44!7xYHe*3BRXjS10NV#$vh*{Kk*sp#fV!VvSLkC zvLr?@1i-*ORnTL2N-Wcjto|N(ib*UPBgSdLGpsILCV?qNwEm8*iZ*A&J_de+*m6}- z83iD88kM?n{UiDbXQt<5U{^c%pyAC#vtkTP(g9%LyTZ;qWWSssGa-ieCc6UqGH|Rj z2rpX(m8(Du0DRa_GitpkzbPhBWJ*r@3;+NOjJ9G5GnND38NNa#`nWh*8l(v>W}+~e z825cl4D4Xw9Y`%z0#&F=7yxu;;M|L3wR6Z8Y`KoZv z7tIY`G4SygI>&-Z6+*FssA^NPv>Eupz{6i->}m!kE0TeXXwT4Qs-VvLU4E*lX!X_a z8Dly#Fq~26EQWz=41A6SgN(Ur#U>R55TJsnxdAY7I3a;*v|tWX-k%k_S{cnunJG+w zsCEZ!jF+=w4DJ^epoyrNA#pCCOuUMWRuGqw5D!FkyJ%zVvlV0Dkc?&q#ATl>#J-ae zU|_VCCWf;S>>$*`dR&AUjdDTt5sm(^s+nkGFz$IPc2@2%Lyze|#2j@{#KL(cd}fKF z<}6cI`3j2mk#aQ<`&z6zJ=E)~;Q#?c1Zrq%sD*_f8?78g9kELwCQhSVTp8wT*y-AT z^Qq`TEA~Ue0#(TH^_2|7wdOBELpNi;5E1j0MEVb#@R^CTb}LuWYy}J;;sCQzuZIQ$ zHCAy!O?9;}5oDp2gHRXU3yoGk$;dog!%1+3FhWs+7Gsm3R#1H=qqlUF396}%01b_X zxb8bzSZ(vh*|JKPRk((<=|Jo~UL-J`2}De}9EI{C-J#S%#DV-Oqi7B9 z``A?*sNTecb-JkASAzlahm~eI(k@5YxWq89%!)C1T-XH>HPayud_FK3*Vsp{$;v;j z7C?xL_AMr>@=AgrD}BmFuWbRoRO6a@Krxq)u0g)xiF^NWWiRh}iRF zk$$c!P9Cx6bj%>+6|C6e-NUSLF$Ee(Z&VJmf<2u6WaB;A1vMUG$y49UFtQLaonLF{ zR;r{o`OKnu70HPxYX^w9_u&j7H)zF1k#Wp!2fh*o&|?EK@f0&_j>OK+G{M5X#VYR*aFmg#~JAGkhk!CQpbbqI&_(xPlF&GgnTtTnsS^r>YfG zsT*|~`Zefc4YXJdg5qmv;g@?EuRKxt^qR;jFkTg-r7+wgrdVF|+&mqKrsh$gM5JzCwSTSNJ(D%4c5rb;zDcI7%MH&msm<)n{Riq$|Y;G$L=wYs|6 zIz8P{$NB@+(lG{N$x*pQauQW<#E-?g0_AO_p1X6-~7|;0ZE8)Nm-Ce z_B&azqtWpN_!Z0r`f)yAOk+bC^cu)pl?dzU9xCt$Ar3mUpR%Q^L8l9Q8INXwl#8ss zHgfMjhCY5|Jbo136^&;Sa2-VV!ZRMx^gKtLK-Jq4vk#6HXVg|Y#+&FMYN`SBk3U}t z4?C8GfGPU9bZzIi*Syz!G%E7P%~RVX7NE{N`kXEdTwdAdi_gklcXk}Y0F6J0zc zAxvWM)5q5T`FJ^3m2XcN=s?twr>PF2Me~GuBDz{Jie#iE+q|&zF-y}icJcYcYp{n~ zkB~rILAHn*^ue=eq9^0I4x)1qb553QndVp-J#46upunki@Z-yCc$c0(f+F!84^g85 zcwUX@Z+L=T5Z#fO&0Df7Vc@@8wT!VN?_XYlyZr3&m>lB~HCDwlJ<)hP!#NTbvPPw!W+VGbW>*6X!vRXW~udyaSL_!13=xPnuCwVED!ST4lO z)5Y@=L}$y>!V*yUt;&1`J$nQP0ssgJF!-5kYyW<< zw&BMsTPH|!P`ePZ$K{xT<7SA09q^1tbX!7}ZPAu3p@{}*y^n& z3Ui%pkd24BgJW)ND${h`{lJSA=oinu5Y5H&Kt$&wWb+nn{i2%cGQoi753lC#-M@f4 z-RVQao8s;Rw0*!`t0O9s(^x#C5{)LJU09qb7EM7iiaKUP$6+j7V!OV*G#;n%OnhMy z6KibE|DXNRGFY<>iauhVOC}mm1Os>c7A=$#p|eS%jFsLRUd_HQUtqB4j?nOS74k+@ zB(G$i+7|l9>f2w{xj2F(O2$KeJ z>pC0y6=6Y+Wj|y=mt%yCWjYob+wkWTCLv(pbC<^UetwCVk>&*H3{19eBdZB@a>8yx z&b4an#M=i5EU_&#ye(r1n2k!8An)p}o5R2!c~{Ovl16Gge;hjzsL(yO)HWd->29^28zF_i1U;uHMSErUYZ) zrM%i*xkJB~E&;Pr#kyp5zCbJIFm|(B?8?)J#sC*C3H@BUjKw9=W6NU18OPEqpsT1? zle4=I9vZ1{UlO_+^W7z_SeC*JwRXdMlU>vW$?4)S^}n2$@)$hH3vkU-U2l62woDgO#??VMzHD6}gyW)7T4K%<$w znq@c3n2QiiT_ml}vG`YPwhgDfb^YAVyn0Nm;r+Rkcdt};F8wsOAH7_^`n`B?8?g=;?887EG?_YC;xFD+2lN^=0)3N-FnQpH1r!Eua-Ft9#Aevf^ z3R+k{m!C2MPD#f5n5e++;A&5FqEgzOxAjw;gk|8fkN_3JavnHLRB@xY&X(x9rHta( zKnB;FD&OA2L{-)YR}%;6je6GV7NqQ%9Z=EwlB%lc+ppe6M{O5>^H6&`t?G| z!)reGQ`T(bYU}pU@%#fdwmG(NF^0w?x@3-l7XuOVDkA+fJ1-I2^7FNuj~=^s|Jv@a zFCoKnY_yDmRhBH`zn(WKA)4-RNr;%GTRI|({MXv{KtUSH`IVHbfdj~ul$4Z^kPsdH zutFAjNdOml?K2DbAOMK-DTL%Bjyj%R9n6F>8LlM)`5sBq4YrTdvFc6AmCIvAW&A_pj=eRoz`>2;U2;S#)^sx zburk<%UH_0576xS#wAEUKoim5fN`HMrc?K*6Kdbm=zPZ}GO$jL!StstW0f|9R;jHa z=}3vj6QJ)x3fKjPRx(kBQ-`s?(ki<-1k_xKYso~DiDSgAP1%L1F5KAk!ZIE^j1}G) zS_7WH1T>tB>->o}DUN|&j%`#0Q_Pd~$YE?p-@h(9LWPa`7Xg>ebu&b*90{9dzwLvI zlf_8B5{4R9Ndbky5e_u;E11FaZN|LY^X2s?0Qa^v|9`v!gCcO<5mB%UVXEj_$3FU1 z>RG-<0zJ$}iq*heUVYk~J>^qAW%ahk9J6vyeJ=)%(Nq>kf!!g%yIYSQ0A0PZu9hg& zg|IKP5ze0R6&@EN4k(Ir=Z}a*M_Eg@|M^swDUG4%ST>_jLf!iRBHj0!Q; za%68IK{uVX5V1yBQf6*A2f!t5!=IO|c#7^MilOZsTgjN|T)y&g<(*W60181r2-Q!t zdYX=5s6fi90RVRA!9!M!wkSGA5Cb2s#9pYBbkD$JFfNfETTadcM}$L=^=VWz2T?!m z*h~MnxXZSGe}(#rFkFPK|MQXb(X?=%n9j?y84eRI=PvgQnlEka_l}5b9rPxG7`n!> zn@S}?-`q|9N-NL4!`RmUdEExrk5h?~Kqv$M6;4ju;p~%}tn;gP>dosVUvj5kKPK6} z&o5)!`s1ZAxGL5}B^8Mo#cw}a(@$syp1FtkZTs;8?)Rltin(vchR)sQ3PWXaF#jS= z2s!C{vLjcrwl>PPe1FyL=^g5Hb+xrSSi$vA__{UQ`0fnxLhKv;^FGwoC%slLKVny_no>^cAduqt#gAh&v_6#Q5CgVITHkGZ=-Kay4oP zC15L#O;rU0gv`*>Vjx~HQFPM6|0}U%QNKS(a+qgZe|$Rp=_8#`sEgwmYp;&DQ*!dp z7aUjZ5Mca2CbBD6a^WIE8L3tS@nT57|7n=#LP5GJTH3L#40IO(8AY9ZnsgKqHPh?9 z(Q{X6XdRC|;w9;orf_WSea9Mm zY)Xvdf#D);eB&E$8SAe;=z~7!gNkpD3>%Mr=SRPbBlq4T)3Kv#*RF$|xn3sit;bV6 z)mqklkDrwcG418;xR<~S}tDH!-+=(*{6V@z~HM0aF{D|T$JN{lcxCMB3D z*cH*#CSd6025ExZpEEo`BV8z=lc*XkiReI7uP=Ge;F2lg*x>t%HBfbchH(bi67%Oo&kwwa3`Q1p$d0YPI0jz1$)Yp%YfyVt76lRG;(Wz|>Tx!D8Luh;aK{3uf*$kAB*11f z(Q?n=9{Wpll^OtWl|)T+am4~Ka3J1pISQEQ9-|VCrq|RE(M|Bg#=_bZk%W%zR-%Mt z@U&Z8GST7aT@F!zDjtAXm8jv^@Ni0!wYkHQ61A|P*W47*^n6d}*z(i(N;kLyqQ&d| zan=ro8de1~zd$U@z%FEa=tM-b^?`NzcmOxWi1}t( z0nrf~iajsKBiNb}?59mMAwBGR3^6du?-_8WnoU%pyad!}i=sOjVPN(iRub6p6ppMW z)MA9(*$F&B7!&-%ic_zj8 z(`_A3;yetl7ck6pA>#3o!2v}f;^6berHZa?>v$I1D$=FK>IdjyIWWy~8x$%zY(SJ17BoSsEX#) zVBm#ICXeIE9Q$A;y)>;d!h){L@ofIwg5<1$x&y$Zij%O8r!(eTq->Nn3c#4@@s8(n zDurDsqZ^g0fPp`o^*f%>O)XnW8O7V@;dn^1WfJ)G#g#7mzi`eur|o!5{R-3Zl>{;H zwPG#x{f;N~IT?5?gn>uHdz0Pqu5A{k@xc03L6f)U zV(9JXbUd_*pR5c#;h6Lc9gpou-k;GwSF5us7_ceFgB#C4|5yO%uJRUkJiLlb$(1gK cq0O3aN@yq2|B?QW^naxPBmE!g|M|ui04#muc>n+a literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..0a5390f963768a0a39cfa58f6d30e1d0d199509e GIT binary patch literal 7718 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 literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000000000000000000000000000000000000..b8e72301e0f7b7f4efaf60a6eb7fee52662a62c9 GIT binary patch literal 5854 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 literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp new file mode 100644 index 0000000000000000000000000000000000000000..dae95ed873f77c0e88a56b5880539a0d0741908e GIT binary patch literal 8314 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 E01HmZuK)l5 literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000000000000000000000000000000000000..e16ef0b03fa9704ca00bb07a75ff2866d3cbd07b GIT binary patch literal 10402 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 M72vGu^g0t40MXOiGynhq literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/values/colors.xml b/nym-vpn/android/app/src/main/res/values/colors.xml new file mode 100644 index 0000000000..d035176a0b --- /dev/null +++ b/nym-vpn/android/app/src/main/res/values/colors.xml @@ -0,0 +1,11 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF1c1b20 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/res/values/ic_banner_background.xml b/nym-vpn/android/app/src/main/res/values/ic_banner_background.xml new file mode 100644 index 0000000000..5274b8a4f3 --- /dev/null +++ b/nym-vpn/android/app/src/main/res/values/ic_banner_background.xml @@ -0,0 +1,4 @@ + + + #121212 + \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/res/values/ic_launcher_background.xml b/nym-vpn/android/app/src/main/res/values/ic_launcher_background.xml new file mode 100644 index 0000000000..9c1cd0cc32 --- /dev/null +++ b/nym-vpn/android/app/src/main/res/values/ic_launcher_background.xml @@ -0,0 +1,4 @@ + + + #1C1B20 + \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/res/values/strings.xml b/nym-vpn/android/app/src/main/res/values/strings.xml new file mode 100644 index 0000000000..2c1d791d4d --- /dev/null +++ b/nym-vpn/android/app/src/main/res/values/strings.xml @@ -0,0 +1,90 @@ + + NymConnect + tunnelConfig + VPN Channel + VPN Notification Channel + Watcher Channel + Watcher Notification Channel + FOREGROUND_FILE + https://github.com/nymtech/nym + https://github.com/nymtech/nym + File is not a .conf file + Turn off tunnel before editing + No tunnels added yet! + Tunnel name already exists + https://discord.com/invite/nym + Watcher Service + Monitoring network state changes + VPN Connected + Connected to tunnel - + 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. + Notifications permission is required for the app to work properly. + Open Settings + Add Trusted SSID + Trusted SSID + Tunnels + Select Tunnel + Enable auto tunneling + Tunnel on mobile data + \"Allow all the time\" location permission is required for retrieving Wi-Fi SSID in the background. Permission is needed for this feature. + Location permission is required for this feature to work properly. + At least one tunnel required to use this feature + "Retry" + View Privacy Policy + Okay + This feature requires background location permission to enable Wi-Fi SSID monitoring even while the application is closed. For more details, please see the Privacy Policy linked on the Support screen. + Background Location Disclosure + TODO + Enter SSID + Submit SSID + [Interface] + Add tunnel from files + File Open + Tunnel Edit + Tunnel Name + Edit + Delete + Add Tunnel + Exclude + Include + Tunnel all applications + Configuration changes saved. + Save changes + Icon + No thanks + Turn on + Map + Bad config. Please try again. + Interface + Public key + Waiting for the Barcode UI module to be downloaded. + Barcode module downloading. Try again. + Addresses + DNS servers + MTU + Peer + Allowed IPs + Endpoint + Transfer + Last handshake + Name + Restart Tunnel + VPN Connection Failed + Failed connection to - + Attempting to connect to server after 30 seconds of no response. + Attempting to reconnect to server after more than one minute of no response. + Enable Always-On VPN support + Please select a tunnel first + Unable to detect Location Services which are required for this feature. Please enable Location Services. + Check again + Detecting Location Services disabled + This feature requires precise location to access Wi-Fi SSID name. Please enable precise location here or in the app settings. + Request + Toggle VPN + No tunnels available + Search packages + Clear Icon + Search Icon + Attempting connection.. + VPN Starting + \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/res/values/themes.xml b/nym-vpn/android/app/src/main/res/values/themes.xml new file mode 100644 index 0000000000..9414a536e4 --- /dev/null +++ b/nym-vpn/android/app/src/main/res/values/themes.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/res/xml/backup_rules.xml b/nym-vpn/android/app/src/main/res/xml/backup_rules.xml new file mode 100644 index 0000000000..fa0f996d2c --- /dev/null +++ b/nym-vpn/android/app/src/main/res/xml/backup_rules.xml @@ -0,0 +1,13 @@ + + + + \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/res/xml/data_extraction_rules.xml b/nym-vpn/android/app/src/main/res/xml/data_extraction_rules.xml new file mode 100644 index 0000000000..9ee9997b0b --- /dev/null +++ b/nym-vpn/android/app/src/main/res/xml/data_extraction_rules.xml @@ -0,0 +1,19 @@ + + + + + + + \ No newline at end of file diff --git a/nym-vpn/android/app/src/test/java/com/zaneschepke/wireguardautotunnel/ExampleUnitTest.kt b/nym-vpn/android/app/src/test/java/com/zaneschepke/wireguardautotunnel/ExampleUnitTest.kt new file mode 100644 index 0000000000..c3453e018c --- /dev/null +++ b/nym-vpn/android/app/src/test/java/com/zaneschepke/wireguardautotunnel/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package net.nymtech.nymconnect + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +} \ No newline at end of file diff --git a/nym-vpn/android/build.gradle.kts b/nym-vpn/android/build.gradle.kts new file mode 100644 index 0000000000..09b1978ecb --- /dev/null +++ b/nym-vpn/android/build.gradle.kts @@ -0,0 +1,19 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + val objectBoxVersion by extra("3.5.1") + val hiltVersion by extra("2.47") + val accompanistVersion by extra("0.31.2-alpha") + + dependencies { + classpath("io.objectbox:objectbox-gradle-plugin:$objectBoxVersion") + classpath("com.google.gms:google-services:4.3.15") + } +} + +plugins { + id("com.android.application") version "8.2.0-beta01" apply false + id("org.jetbrains.kotlin.android") version "1.8.22" apply false + id("com.google.dagger.hilt.android") version "2.44" apply false + kotlin("plugin.serialization") version "1.8.22" apply false +} diff --git a/nym-vpn/android/gradle.properties b/nym-vpn/android/gradle.properties new file mode 100644 index 0000000000..1023be831f --- /dev/null +++ b/nym-vpn/android/gradle.properties @@ -0,0 +1,25 @@ +# Project-wide Gradle settings. +# IDE (e.g. Android Studio) users: +# Gradle settings configured through the IDE *will override* +# any settings specified in this file. +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8 +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true +# AndroidX package structure to make it clearer which packages are bundled with the +# Android operating system, and which are packaged with your app's APK +# https://developer.android.com/topic/libraries/support-library/androidx-rn +android.useAndroidX=true +# Kotlin code style for this project: "official" or "obsolete": +kotlin.code.style=official +# Enables namespacing of each library's R class so that its R class includes only the +# resources declared in the library itself and none from the library's dependencies, +# thereby reducing the size of the R class for that library +android.nonTransitiveRClass=true +#enable buildconfig values +android.defaults.buildfeatures.buildconfig=true \ No newline at end of file diff --git a/nym-vpn/android/gradle/wrapper/gradle-wrapper.jar b/nym-vpn/android/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f GIT binary patch literal 59203 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

K7UpUK$>l@ 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 E2O(~oYXATM literal 0 HcmV?d00001 diff --git a/nym-vpn/android/gradle/wrapper/gradle-wrapper.properties b/nym-vpn/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000..96f2e7a959 --- /dev/null +++ b/nym-vpn/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Mon Apr 24 22:46:45 EDT 2023 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/nym-vpn/android/gradlew b/nym-vpn/android/gradlew new file mode 100755 index 0000000000..4f906e0c81 --- /dev/null +++ b/nym-vpn/android/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/nym-vpn/android/gradlew.bat b/nym-vpn/android/gradlew.bat new file mode 100644 index 0000000000..107acd32c4 --- /dev/null +++ b/nym-vpn/android/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/nym-vpn/android/settings.gradle.kts b/nym-vpn/android/settings.gradle.kts new file mode 100644 index 0000000000..aaebe93cd6 --- /dev/null +++ b/nym-vpn/android/settings.gradle.kts @@ -0,0 +1,18 @@ +pluginManagement { + repositories { + google() + mavenCentral() + gradlePluginPortal() + } +} +dependencyResolutionManagement { + repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) + repositories { + google() + mavenCentral() + } +} + +rootProject.name = "NymConnect" +include(":app") + \ No newline at end of file From 77a56600f0d14d0dc73b8933db6db8f1d4f5ded3 Mon Sep 17 00:00:00 2001 From: pierre Date: Thu, 7 Sep 2023 16:34:37 +0200 Subject: [PATCH 2/2] fix build, add icon launcher --- .../android/app/src/main/AndroidManifest.xml | 2 +- .../drawable-v24/ic_launcher_foreground.xml | 30 ++++++++++++++++++ .../main/res/mipmap-anydpi-v26/ic_banner.xml | 5 --- .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3357 bytes .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 2004 -> 0 bytes .../mipmap-hdpi/ic_launcher_foreground.png | Bin 0 -> 5427 bytes .../mipmap-hdpi/ic_launcher_foreground.webp | Bin 2936 -> 0 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5381 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 3568 -> 0 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 1757 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 1268 -> 0 bytes .../mipmap-mdpi/ic_launcher_foreground.png | Bin 0 -> 2753 bytes .../mipmap-mdpi/ic_launcher_foreground.webp | Bin 1926 -> 0 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2775 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 2242 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_banner.png | Bin 3578 -> 0 bytes .../res/mipmap-xhdpi/ic_banner_foreground.png | Bin 3770 -> 0 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4226 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 2728 -> 0 bytes .../mipmap-xhdpi/ic_launcher_foreground.png | Bin 0 -> 8196 bytes .../mipmap-xhdpi/ic_launcher_foreground.webp | Bin 3956 -> 0 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7277 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 5030 -> 0 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7664 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 4246 -> 0 bytes .../mipmap-xxhdpi/ic_launcher_foreground.png | Bin 0 -> 15273 bytes .../mipmap-xxhdpi/ic_launcher_foreground.webp | Bin 6154 -> 0 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 12925 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 7718 -> 0 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 11075 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 5854 -> 0 bytes .../mipmap-xxxhdpi/ic_launcher_foreground.png | Bin 0 -> 24100 bytes .../ic_launcher_foreground.webp | Bin 8314 -> 0 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 18743 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 10402 -> 0 bytes .../res/values/ic_launcher_background.xml | 2 +- nym-vpn/android/build.gradle.kts | 2 +- 37 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 nym-vpn/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_banner.xml create mode 100644 nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_banner.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_banner_foreground.png create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp create mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png delete mode 100644 nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp diff --git a/nym-vpn/android/app/src/main/AndroidManifest.xml b/nym-vpn/android/app/src/main/AndroidManifest.xml index 2ff4f063bb..391dff34b2 100644 --- a/nym-vpn/android/app/src/main/AndroidManifest.xml +++ b/nym-vpn/android/app/src/main/AndroidManifest.xml @@ -42,7 +42,7 @@ android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" - android:banner="@mipmap/ic_banner" + android:banner="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" diff --git a/nym-vpn/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/nym-vpn/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000000..2b068d1146 --- /dev/null +++ b/nym-vpn/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_banner.xml b/nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_banner.xml deleted file mode 100644 index cf3108b364..0000000000 --- a/nym-vpn/android/app/src/main/res/mipmap-anydpi-v26/ic_banner.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..4974445c9ab3aea5d84fadbc81b783135062e19e GIT binary patch literal 3357 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 literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp deleted file mode 100644 index 52206777aa3245f61ae885e0825057c0550c2f0e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2004 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 literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp deleted file mode 100644 index bc0c1b6637c254c08d155d433516afbc3fed7fa9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2936 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 literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/nym-vpn/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp deleted file mode 100644 index 9adc4b2092b1a5859c41e628674c4dc086ea3680..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3568 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 literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp deleted file mode 100644 index 3d0be44a979f4be1591d5a3b292e11c728694407..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1268 zcmVj?Zg>an7&^#H7odksD^s;#igNw!_LgO+Bm(U0q2Sb(#VA!^8 z*f4?E$#%~knA-pV$R@UJ8&{-j-}48?Ro3WEfZY85*Ev}PcXxNEba!`mcXxL=iTuyq zWx3ezpGl~$TG)Vx{surdVGKGJ zaCgd7{}#Da5N+EoB-Q_~m6U?Y%S)+yY}>YN+eTFx3|K^^|1UQEp8#x10wzDA9`g~9 zBS7~Y4hS-PJodWEpI?AyI2cNFz;-WtQNR2DfoF-1WdA|3P6;qAf>A_|Ci|56s@KMH znqh)~6VI5tRQ6^S@m?A4ePSy-r_Ed@a}8u->m2(sO1?Vh|1%idMy14?r8VulFj|=Evn!{(U1B2h;Ur-y28J91 zV9Jmfm3px?Di_AcFfo?07&%IeLjxz`0-k2L6dRp@#K9stBNFI+<|+V;m>fpM-)%@y znCSiLJr=R3{VtQ30l(;q_5mJ2>Gavd2_uv1?^EaY=yL5VpSuICi-i;6D6u-LsA>d- zi#33&ZlSLy3J}qxemNB!#~2_8f+Zr6*_QF66G0S3;<6-Efe%x*{D)7?N1~CPlG~lf zS?k8*@r-SnY?+x+-OB?O3sfGVfCZ6NH-Umn+qIr(X1}0vuuA|mIx?}#k-em$&>$9p zlwnkCDDq(niW^(-%S2zHv~dIgvKr<7GY=_kw-lYm;>-@21zNog+HYL;*W zFRS00_@b73XN~Gr7+#nJA`d|AV3Wv!aKI7LZEa02v*m&F<3Kn>>#}#LAc76C8YYe? zYw-b4w%kK!#*2&vG8(VA`nOdP7q6(@%}BqzlE#_(vcP$)C<|NxvuYn=YCfGK7Y*3u0b0!;1?on e(REB;y+!YEab!Dz5j4T6Z;y`LSMs6iS8Pg*JY-e? diff --git a/nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..e634763b4228461b0c4c5c494d37e6022ffec34e GIT binary patch literal 2753 zcmaJ@c{mhm7snLFP!eV`$di2;+)TFYSxXqpFt%&5HJYr^GBl*2Fk=}aTf(@)Fp?#V zVPq#U$)L@Z5F!d=>r?lBe}3N|=RN0npR+x`-+9h+?mO672?D6ZE@T7jCbZz@ful0_`q0dbKX zn~#W$m>#2q0UfeWzx-zII{78&!yI&BH@rG^*l_c#g#}NXiHtD+q5q+LcDOApYLuy7 ziOz`w)JdFr<=orruWR0tgPc~L-D+@kY+JgZOawdjgTZpMDS?)p`oQy;c}5A`vsDfM zW(8@7t9X2QDe{(AhXRlEupOnY#Rg-H_quxB5aH31?QEq}r0I}X8#BvGc>>O?W4A2< zM0u429Uuqa*uA3s?v2XiqWm>=WktGurafP^>LWpT+)y2PA9qKnxT(O!-E~~7zVeD? zWFcQYz#|Xj0IA}SP(-i|NVLSYiT6AGA=_V-iG{c?;KC3DTUJy%m6?G;uPJNvD$-)~ zxz-ffq(5_ANITU^CvR5HGc?>3gHr2|iwn)v$mtZx8IfbEU-WB<@HCXZWL>G=+bm~V59R& z>SJ1uC#3hJ;GJkWP1!Ntd^mmzU^?e9+0_t6Wf&5ev7o#QO$C3fo>?j8Saw)Sk*ac{ zuZ5C;WYQrMBT4JN`g1d(x?AEyA0G4qhO#D2cH{(p@qx8jyu#q7Q@h~TE8PrE)4+sx z8H+s13!z-4oAEMq9k?<>$I~XFQOvy^@u=ywK2@lwDut#u#zN4$> z+6Gd19Z&o9hQmPoA`lCjq#&(9>kWnut#+)7m06QMSU}7?8GzoG`Y`n^_i>9S#M-43G!;#XG zWqCeT;90Nyd(H`;b2JxxbmgV)U3(>Y0f3k*G-n&dGr0(q4DJ?8*;nY{kVLyDr&~ph zA-oIiy-P=DN0_MY^9jqY2#6+nGIRhY(Ws)^9Bh38Evx~3ZaMS7Tq?NQ6yGp)6+1^86+Q}YgD$%fG62MeF`3|oLNp6 zkbhz;o`e&W_IRIa!Br$aL~UpjgZtE{KQ}_ADEnN8CY~lZRKpAs^W=YOg~9|BmQCcIB3y)vQqM} zN78=!I_{Q~A+3)I(Y+u!%-@L=xl$a)ig)5H4m5Ti!^skBz;Et9bJhFV9rftI`Op;f zyF03#3*8@=-tCX3j4Z-~gM6?{kuX1e#<2t^j*zYPQ<_~Vy&qj5U50-hmf)=lg2<%2 zth1cQbDmy4cPVA9o-A6Asw2b`r0qi^qLqO_`rEE(1=YWyDgw%feW97>uu>Xd8a*tXKag?i1KiZn!D& zX*bI|m75pnQMJ{4$jU7Pn7l%K_xK>7xU7kG6H>Qa^ex(_z#5lD7VnPOH;0Hblu*h4_AsDJP)?Q&Q<7yep}VM*pf@rQ5;!K%pEn6)vsjioU#Z&gu6(ZnRicgxR^4<-3*ui{sjgP^D-PxTjS$sLV-!$jB z6^4fH)RN&SD^Wq=ZfT$M{^^0LM>S!{CVx-^f2%cQ=i-L_Hup34;I16VoYDzOxCC0NdXzA?xb*PNaUrEMUWzlT(S8uoiM&W(_a#PDUbbBJzF_tIShFc@AsQbQ5|=_O-#2 zWaHJqB>1?05`1PeTWK^O6m|B6c8NxOb>wv;?Pfv!s!UUSbA{k7uTW%#kT{akFr*Ok zs+~ZpRI>GDI^TX38^ksRwEZ-`{BgcW<%mS@@v$-Qk{{RJMo%E5pLSmL@Uyzfeseo4 zjea@XsDGwzKVb`jM2 zqtf!bF;%{{A2h&+vT*6Gjpu<9go^=3qSrl<_FhYfQNA`*`Re`ucjcMLunqS4TE0W} Vq;%h-4o*`p8w)%0YBQfZ{{dDXCT9Qu literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp deleted file mode 100644 index 106e0e13cc5996f9e412a6277c365a55550b330d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1926 zcmV;12YL8XNk&F~2LJ$9MM6+kP&iC+2LJ#sYrq;1HPN;9|Mca|eZ;nt+O}=mw(T6- z=FBnvzwa-;fn1OFckexG?S0zhH|S3HX`|8=FJii^wPUu^#kmICcDk%oPAYY?(wViZ zL6vIyu(QqDMrYeem7H$6X_MBr*`_pZVpgssg>2il)3!=}vVUWCm?K-Z&OTC@p}ow^ z%*;$r%pkdqBuSFII;#X9Ay+8~ZQHi7c`|3)wr$(C-A#a+ ze1MX4A@*7zUGomf$xZN?0Ku1WqTgBa3c<-na3h`RWi}EF1bZfQe}&}@0;x&x3?FuH zRuK&dcIEVwY&&Bm|4R^WyO>3SO$nWR1j`8i11^-iQve8_3r@$0yq_SOA#w(icH{Ym zrj=^z6Racn0{}S+Pp_aQxF%R%(My6EnWVHZDQ77nw*Z0tKx@r~mq$|f+El2_>TBr8_=TmTU5DT$@t!9*@I9f239cRr0P|Uj*lP~HL1jq52lUn;!{)msrILQ54~sK6Y9(CT?Gyu9*oaITovtP1i&IVYxTxX8sDO6H%$?3W4z&emFRS$Ce^^WzM7^MlVuWk|8TCCQ{Oi z8F6jm>%`U=Az3|-UmU>&OA$OmOotw)BfMM@<%%p5S*>2WV+5?2Do2c9)|mZa4wdqO zOo^`#fcQp5l#3(SVW~Bcrt$2oG8>%`S7RW#JSEY!imKM&Sfl8rm(s7{4#$wkB4$>M zhg-P{AYGPU0D!nUk(J^ImRL$+4}yO+BL;}6Rdf}d!H-{R`tztN`*5nxK03Sok*fjl zj*9?F`sWJ3u6uF><18h(D~rl7N22P?!>Rt?qqd(n$7%b~k)zl!2MpZAg$1MvUIMV^ zuAEfc+)@NHb^L<*-#}`gT7TV~)}9_|y%NlzCoa`w9!~emi@RIHRA_tkN;UvRLB_}vw4`vmRb9-hK@!R#)>Eh#gUu7L=5A zbQaZnxw`)kCwx&FwEFCD`n+&q5}SmT3cxQ(nw*rZgu;rT?!ukcQUnjpC5+2?B}c>b zcJbo0|KNiuvmFeQ+C~;5SjG9}%0Se-oNE6+zz%%!;;`g_j58x2*syTZ$7f zQrTiff_vr+2Coa)ZR92?5{BUY1mYWK4@#=-%@vUhC)QeXR|rz z?=6O4va-o(|6^i#bvAi-eyzc?LtY~_RIl(0RSGa^T(sM zUyp^W7>HaH^ob2uw)qpm2~B2#k6++tiKuYPW=W%pomSMm21z4i8IkjXKEa(dk#PG^ z!lWF*UjSJt!!(x833owzi6CH5a2hH*6)+1xil&3*>kgewm@yp$FmQ~r)y!d{4+HQG z_*s|?rrpJBq~_Yor$i64SCTS|rMzSO1{uC{JL%UJA%n|1^f{4yFJo@6jJwyg=|#PzotK9*6$q*a`eBn=o!R z&~7VfYAbu*o7ih^Yvvm_yEFvuKI*1{jatJELsbvSmkW(c$cMFt83me`ViC z|D%aDD-tV3u=2_)CrAcvuW#@rVS6b%U+G!s=Mo-nf#9pqX{zk~{HyeG6rOJVe5SH{ z(MyD+-KevSo0a{7lTF!wMS_{@XilTll$ebK7s@0cPn4t$!583d7pIQOD_uxYNqbh( MZk0*0tH~@60R0}G`2YX_ diff --git a/nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/nym-vpn/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..37a8d502c816c311a411b1fea2d11c5fcf7403b2 GIT binary patch literal 2775 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 Q3Dna|FWs`0M)6J<0KA+ky8r+H diff --git a/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_banner.png b/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_banner.png deleted file mode 100644 index fbd39f501dd7a23fb706d9c597bdec9b3c511e5e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3578 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 BaRvYY diff --git a/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_banner_foreground.png b/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_banner_foreground.png deleted file mode 100644 index 634417a64034f28adeff6c7c3c5b29d0a2fb2908..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3770 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 Ye`O;&88BhdfB*mh07*qoM6N<$g6^2_>;M1& literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp deleted file mode 100644 index 2dddd0313fbe47649a26f3bd19e022d9b439ad86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2728 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 HCI7Z-pl{|&eziJ8a?ga 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 O>pytM>i)0$zdmieM{+&@ diff --git a/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..51a588fdee975c7d501522c1b820d9eede4e4c5f GIT binary patch literal 7277 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 Hu0mjfVx7ws literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/nym-vpn/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp deleted file mode 100644 index c89a4abd0e7daace668cc1a0b61de43fff99bf6e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5030 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 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..65cefcb1963b4062142389ea078ed10cd81f2347 GIT binary patch literal 7664 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 DA@h_v literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp deleted file mode 100644 index bf191eb8171c41c8f46e66be48b647099254f843..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4246 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 literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp deleted file mode 100644 index b3336b2e2815906eadc3895cb94c59b5a5b0df36..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6154 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 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..5070e583a0482cf1902201b3ea4c51c81440afe9 GIT binary patch literal 12925 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 Zd9WUlq0l)&o_{L=s48l`s+YHp_3w literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/nym-vpn/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp deleted file mode 100644 index 0a5390f963768a0a39cfa58f6d30e1d0d199509e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7718 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 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..18252905f84787dd51dccc08148c663439ebfaf7 GIT binary patch literal 11075 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 NSwUUCT+Slo{{aNteX{@n literal 0 HcmV?d00001 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp deleted file mode 100644 index b8e72301e0f7b7f4efaf60a6eb7fee52662a62c9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5854 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 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png new file mode 100644 index 0000000000000000000000000000000000000000..514ec36652ee118e7a4e9e923e31a3b356305347 GIT binary patch literal 24100 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 E01HmZuK)l5 diff --git a/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/nym-vpn/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..83e115a87dd13ec5bc791eabcf7c70fc96556d7c GIT binary patch literal 18743 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 M72vGu^g0t40MXOiGynhq diff --git a/nym-vpn/android/app/src/main/res/values/ic_launcher_background.xml b/nym-vpn/android/app/src/main/res/values/ic_launcher_background.xml index 9c1cd0cc32..a3b9258141 100644 --- a/nym-vpn/android/app/src/main/res/values/ic_launcher_background.xml +++ b/nym-vpn/android/app/src/main/res/values/ic_launcher_background.xml @@ -1,4 +1,4 @@ - #1C1B20 + #1D2125 \ No newline at end of file diff --git a/nym-vpn/android/build.gradle.kts b/nym-vpn/android/build.gradle.kts index 09b1978ecb..1a6937f39a 100644 --- a/nym-vpn/android/build.gradle.kts +++ b/nym-vpn/android/build.gradle.kts @@ -12,7 +12,7 @@ buildscript { } plugins { - id("com.android.application") version "8.2.0-beta01" apply false + id("com.android.application") version "8.2.0-beta02" apply false id("org.jetbrains.kotlin.android") version "1.8.22" apply false id("com.google.dagger.hilt.android") version "2.44" apply false kotlin("plugin.serialization") version "1.8.22" apply false