├── app ├── .gitignore ├── src │ ├── main │ │ ├── res │ │ │ ├── font │ │ │ │ ├── open_sans_bold.ttf │ │ │ │ ├── open_sans_light.ttf │ │ │ │ ├── open_sans_italic.ttf │ │ │ │ ├── open_sans_regular.ttf │ │ │ │ ├── open_sans_semibold.ttf │ │ │ │ ├── open_sans_extra_bold.ttf │ │ │ │ ├── open_sans_bold_italic.ttf │ │ │ │ ├── open_sans_light_italic.ttf │ │ │ │ ├── open_sans_semibold_italic.ttf │ │ │ │ └── open_sans_extra_bold_italic.ttf │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ ├── ic_launcher_background.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ ├── ic_launcher_background.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── drawable-hdpi │ │ │ │ └── logo_black.png │ │ │ ├── drawable-mdpi │ │ │ │ └── logo_black.png │ │ │ ├── drawable-xhdpi │ │ │ │ └── logo_black.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ ├── ic_launcher_background.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ ├── ic_launcher_background.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── drawable-xxhdpi │ │ │ │ ├── logo_black.png │ │ │ │ ├── surfnet_logo.png │ │ │ │ ├── external_provider.png │ │ │ │ ├── maintenance_icon.png │ │ │ │ ├── icon_shield_access_white_full.png │ │ │ │ └── icon_shield_internet_white_full.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_launcher.png │ │ │ │ ├── ic_launcher_round.png │ │ │ │ ├── ic_launcher_background.png │ │ │ │ └── ic_launcher_foreground.png │ │ │ ├── values │ │ │ │ ├── attrs.xml │ │ │ │ ├── ids.xml │ │ │ │ ├── dimens.xml │ │ │ │ ├── content_description.xml │ │ │ │ └── colors.xml │ │ │ ├── drawable │ │ │ │ ├── dialog_background.xml │ │ │ │ ├── loading_gradient.xml │ │ │ │ ├── delete_icon.xml │ │ │ │ ├── button_bg.xml │ │ │ │ ├── dialog_button_bg.xml │ │ │ │ ├── bg_search.xml │ │ │ │ ├── scrollbar_thumb.xml │ │ │ │ ├── access_type_bg.xml │ │ │ │ ├── ic_chevron_right.xml │ │ │ │ ├── ic_add.xml │ │ │ │ ├── ic_arrow_drop_down.xml │ │ │ │ ├── ic_warning.xml │ │ │ │ ├── switch_thumb.xml │ │ │ │ ├── ic_institute.xml │ │ │ │ ├── bg_progressbar_indeterminate.xml │ │ │ │ ├── ic_search.xml │ │ │ │ ├── ic_vpn_profile.xml │ │ │ │ ├── ic_secure_internet.xml │ │ │ │ ├── ic_server.xml │ │ │ │ ├── switch_track.xml │ │ │ │ ├── bg_progress_indeterminate_layers.xml │ │ │ │ ├── ic_help.xml │ │ │ │ ├── ic_settings.xml │ │ │ │ └── ic_connection_status_connecting.xml │ │ │ ├── interpolator │ │ │ │ ├── progress_indeterminate_horizontal_rect1_scalex.xml │ │ │ │ ├── progress_indeterminate_horizontal_rect1_translatex.xml │ │ │ │ ├── progress_indeterminate_horizontal_rect2_translatex.xml │ │ │ │ └── progress_indeterminate_horizontal_rect2_scalex.xml │ │ │ ├── anim │ │ │ │ ├── progress_indeterminate_horizontal_rect1.xml │ │ │ │ ├── progress_indeterminate_horizontal_rect2.xml │ │ │ │ ├── fade_in.xml │ │ │ │ └── fade_out.xml │ │ │ ├── layout │ │ │ │ ├── activity_main.xml │ │ │ │ ├── activity_settings.xml │ │ │ │ ├── activity_openvpn_logs.xml │ │ │ │ ├── activity_licenses.xml │ │ │ │ ├── list_item_provider.xml │ │ │ │ ├── activity_api_logs.xml │ │ │ │ ├── fragment_profile_selection.xml │ │ │ │ ├── list_item_message.xml │ │ │ │ ├── dialog_error.xml │ │ │ │ └── list_item_profile.xml │ │ │ ├── mipmap-anydpi-v26 │ │ │ │ ├── ic_launcher.xml │ │ │ │ └── ic_launcher_round.xml │ │ │ ├── color │ │ │ │ └── bg_big_button.xml │ │ │ ├── values-de │ │ │ │ └── content_description.xml │ │ │ ├── values-ca │ │ │ │ └── content_description.xml │ │ │ ├── values-es │ │ │ │ └── content_description.xml │ │ │ └── menu │ │ │ │ └── logmenu.xml │ │ └── java │ │ │ └── nl │ │ │ └── eduvpn │ │ │ └── app │ │ │ ├── livedata │ │ │ ├── ByteCount.kt │ │ │ ├── IPs.kt │ │ │ ├── openvpn │ │ │ │ └── ByteCountLiveData.kt │ │ │ ├── UnlessDisconnectedLiveData.kt │ │ │ └── ConnectionTimeLiveData.kt │ │ │ ├── utils │ │ │ ├── Listener.kt │ │ │ ├── WireGuardTunnel.kt │ │ │ └── serializer │ │ │ │ ├── DateSerializer.kt │ │ │ │ └── TranslatableStringSerializer.kt │ │ │ ├── entity │ │ │ ├── VPNConfig.kt │ │ │ ├── exception │ │ │ │ ├── ExceptionMessage.kt │ │ │ │ ├── EduVPNException.kt │ │ │ │ └── CommonException.kt │ │ │ ├── CookieAndStringData.kt │ │ │ ├── Profile.kt │ │ │ ├── CertExpiryTimes.kt │ │ │ ├── SerializedVpnConfig.kt │ │ │ ├── CookieAndProfileMapData.kt │ │ │ ├── ServerList.kt │ │ │ ├── OrganizationList.kt │ │ │ ├── Organization.kt │ │ │ ├── AuthorizationType.kt │ │ │ ├── Instance.kt │ │ │ ├── CurrentServer.kt │ │ │ └── AddedServers.kt │ │ │ ├── viewmodel │ │ │ ├── ApiLogsViewModel.kt │ │ │ ├── SettingsViewModel.kt │ │ │ ├── ProfileSelectionViewModel.kt │ │ │ ├── ConnectionState.kt │ │ │ ├── AddServerViewModel.kt │ │ │ └── ViewModelFactory.kt │ │ │ ├── DisconnectVPNBroadcastReceiver.kt │ │ │ ├── inject │ │ │ ├── ViewModelKey.kt │ │ │ ├── EduVPNComponent.kt │ │ │ └── ViewModelModule.kt │ │ │ ├── base │ │ │ ├── BaseActivity.kt │ │ │ └── BaseFragment.kt │ │ │ ├── Constants.kt │ │ │ ├── ApiLogsActivity.kt │ │ │ ├── service │ │ │ ├── VPNService.kt │ │ │ └── OrganizationService.kt │ │ │ ├── OpenVpnLogsActivity.kt │ │ │ ├── adapter │ │ │ ├── viewholder │ │ │ │ └── ProfileViewHolder.kt │ │ │ └── ProfileAdapter.kt │ │ │ ├── LicenseActivity.kt │ │ │ ├── EduVPNApplication.java │ │ │ ├── CertExpiredBroadcastReceiver.kt │ │ │ └── SettingsActivity.kt │ ├── gov │ │ └── res │ │ │ ├── drawable-hdpi │ │ │ └── logo_black.png │ │ │ ├── drawable-mdpi │ │ │ └── logo_black.png │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.webp │ │ │ ├── ic_launcher_round.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.webp │ │ │ ├── ic_launcher_round.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── drawable-xhdpi │ │ │ └── logo_black.png │ │ │ ├── drawable-xxhdpi │ │ │ └── logo_black.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.webp │ │ │ ├── ic_launcher_round.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.webp │ │ │ ├── ic_launcher_round.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── drawable-xxxhdpi │ │ │ └── logo_black.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.webp │ │ │ ├── ic_launcher_round.webp │ │ │ └── ic_launcher_foreground.webp │ │ │ ├── values │ │ │ ├── ic_launcher_background.xml │ │ │ ├── strings.xml │ │ │ └── colors.xml │ │ │ └── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ ├── home │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_background.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_background.png │ │ │ ├── drawable-hdpi │ │ │ └── logo_black.png │ │ │ ├── drawable-mdpi │ │ │ └── logo_black.png │ │ │ ├── drawable-xhdpi │ │ │ └── logo_black.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_background.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_background.png │ │ │ ├── drawable-xxhdpi │ │ │ └── logo_black.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ ├── ic_launcher_round.png │ │ │ └── ic_launcher_background.png │ │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ │ ├── values │ │ │ ├── strings.xml │ │ │ └── colors.xml │ │ │ ├── values-de │ │ │ └── strings.xml │ │ │ ├── values-es │ │ │ └── strings.xml │ │ │ └── drawable │ │ │ ├── ic_application_logo.xml │ │ │ └── ic_launcher_foreground.xml │ ├── dev │ │ └── res │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── colors.xml │ └── androidTest │ │ └── java │ │ └── nl │ │ └── eduvpn │ │ └── app │ │ ├── UnitTestSuite.java │ │ ├── utils │ │ └── ParcelableTest.kt │ │ ├── WaitUntilGoneAction.kt │ │ └── ui_test │ │ └── BrowserTest.kt └── proguard-rules.pro ├── common ├── .gitignore ├── consumer-rules.pro ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── org │ │ └── eduvpn │ │ └── common │ │ ├── ServerType.java │ │ ├── Protocol.java │ │ ├── DataErrorTuple.java │ │ └── FailoverResult.java ├── proguard-rules.pro └── build.gradle ├── fastlane └── metadata │ └── android │ └── en-US │ ├── title.txt │ ├── changelogs │ ├── 16.txt │ ├── 11.txt │ ├── 29.txt │ ├── 15.txt │ ├── 21.txt │ ├── 30.txt │ ├── 7.txt │ ├── 23.txt │ ├── 22.txt │ ├── 26.txt │ ├── 12.txt │ ├── 17.txt │ ├── 25.txt │ ├── 18.txt │ ├── 31.txt │ ├── 14.txt │ ├── 24.txt │ ├── 19.txt │ ├── 20.txt │ ├── 13.txt │ ├── 27.txt │ ├── 9.txt │ ├── 28.txt │ ├── 6.txt │ └── 10.txt │ ├── short_description.txt │ ├── images │ ├── icon.png │ ├── featureGraphic.png │ └── phoneScreenshots │ │ ├── 090-Settings.jpg │ │ ├── 080-ConnectionInfo.jpg │ │ ├── 011-FirstScreenNthUse.jpg │ │ ├── 010-FirstScreenFirstUse.jpg │ │ ├── 030-ServerSearchResults.jpg │ │ ├── 050-ConnectedToSecureInternet.jpg │ │ ├── 040-ConnectingToSecureInternet.jpg │ │ ├── 061-ConnectedToInstituteAccess.jpg │ │ ├── 031-ServerSearchResultsWith2dots.jpg │ │ └── 070-NotConnectedToSecureInternet.jpg │ └── full_description.txt ├── .gitignore ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── .gitmodules ├── create_release_tar.sh ├── NEW_RELEASE.md ├── gradle.properties └── settings.gradle /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /common/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | .cxx/ -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/title.txt: -------------------------------------------------------------------------------- 1 | eduVPN 2 | -------------------------------------------------------------------------------- /common/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -keep public class org.eduvpn.common.** { *; } -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/16.txt: -------------------------------------------------------------------------------- 1 | * Update ics-openvpn 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/11.txt: -------------------------------------------------------------------------------- 1 | * Update ics-openvpn to version v0.7.13 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/29.txt: -------------------------------------------------------------------------------- 1 | - bump release for Google Play Store 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/15.txt: -------------------------------------------------------------------------------- 1 | * Fix certificate expiry countdown 2 | * Fix UI tests 3 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/21.txt: -------------------------------------------------------------------------------- 1 | * update ics-openvpn 2 | * Remove secure-preferences (#117) 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | .DS_Store 5 | /build 6 | /.idea 7 | /captures 8 | *.apk 9 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/30.txt: -------------------------------------------------------------------------------- 1 | - embed WireGuard for Android 2 | - fix crash when reconnecting 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/7.txt: -------------------------------------------------------------------------------- 1 | * Use different OAuth client information for Let's Connect! flavor 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/23.txt: -------------------------------------------------------------------------------- 1 | * Only sort organizations when retrieving lists, not on every keypress 2 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/short_description.txt: -------------------------------------------------------------------------------- 1 | eduVPN connects securely and encrypted to your institution or Internet 2 | -------------------------------------------------------------------------------- /app/src/main/res/font/open_sans_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/font/open_sans_bold.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/open_sans_light.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/font/open_sans_light.ttf -------------------------------------------------------------------------------- /app/src/gov/res/drawable-hdpi/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/drawable-hdpi/logo_black.png -------------------------------------------------------------------------------- /app/src/gov/res/drawable-mdpi/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/drawable-mdpi/logo_black.png -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/home/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/home/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/font/open_sans_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/font/open_sans_italic.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/open_sans_regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/font/open_sans_regular.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/open_sans_semibold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/font/open_sans_semibold.ttf -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/gov/res/drawable-xhdpi/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/drawable-xhdpi/logo_black.png -------------------------------------------------------------------------------- /app/src/gov/res/drawable-xxhdpi/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/drawable-xxhdpi/logo_black.png -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/home/res/drawable-hdpi/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/drawable-hdpi/logo_black.png -------------------------------------------------------------------------------- /app/src/home/res/drawable-mdpi/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/drawable-mdpi/logo_black.png -------------------------------------------------------------------------------- /app/src/home/res/drawable-xhdpi/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/drawable-xhdpi/logo_black.png -------------------------------------------------------------------------------- /app/src/home/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/home/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/drawable-hdpi/logo_black.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/drawable-mdpi/logo_black.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/drawable-xhdpi/logo_black.png -------------------------------------------------------------------------------- /app/src/main/res/font/open_sans_extra_bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/font/open_sans_extra_bold.ttf -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/gov/res/drawable-xxxhdpi/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/drawable-xxxhdpi/logo_black.png -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /app/src/home/res/drawable-xxhdpi/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/drawable-xxhdpi/logo_black.png -------------------------------------------------------------------------------- /app/src/home/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/logo_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/drawable-xxhdpi/logo_black.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/surfnet_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/drawable-xxhdpi/surfnet_logo.png -------------------------------------------------------------------------------- /app/src/main/res/font/open_sans_bold_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/font/open_sans_bold_italic.ttf -------------------------------------------------------------------------------- /app/src/main/res/font/open_sans_light_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/font/open_sans_light_italic.ttf -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/fastlane/metadata/android/en-US/images/icon.png -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/home/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/home/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/home/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/font/open_sans_semibold_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/font/open_sans_semibold_italic.ttf -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/22.txt: -------------------------------------------------------------------------------- 1 | * Remove API v2 support 2 | * Added German translation 3 | * Remove save button 4 | * Bug fixes 5 | -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /app/src/home/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/home/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/livedata/ByteCount.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.livedata 2 | 3 | data class ByteCount(val bytesIn: Long, val bytesOut: Long) 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/external_provider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/drawable-xxhdpi/external_provider.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/maintenance_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/drawable-xxhdpi/maintenance_icon.png -------------------------------------------------------------------------------- /app/src/main/res/font/open_sans_extra_bold_italic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/font/open_sans_extra_bold_italic.ttf -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/26.txt: -------------------------------------------------------------------------------- 1 | - fix incorrect usage of seconds, should be ms 2 | - fix not being able to add secure internet servers 3 | -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-hdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-hdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-mdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-mdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-xhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-xhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /app/src/home/res/mipmap-hdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-hdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/home/res/mipmap-mdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-mdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/home/res/mipmap-xhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-xhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/12.txt: -------------------------------------------------------------------------------- 1 | * Continue to add server screen if selection screen is empty 2 | * Fix app being stuck in creating keypair 3 | -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-xxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-xxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-xxxhdpi/ic_launcher_foreground.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/gov/res/mipmap-xxxhdpi/ic_launcher_foreground.webp -------------------------------------------------------------------------------- /app/src/home/res/mipmap-xxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-xxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/home/res/mipmap-xxxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/home/res/mipmap-xxxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_background.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /common/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/17.txt: -------------------------------------------------------------------------------- 1 | * Add Spanish (Latin America) translation 2 | * Fix parallel installation issue with other ics-openvpn based apps 3 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/25.txt: -------------------------------------------------------------------------------- 1 | * update all build scripts for new release 2 | * create new tag to properly update CHANGES.md and fastlane files 3 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/featureGraphic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/fastlane/metadata/android/en-US/images/featureGraphic.png -------------------------------------------------------------------------------- /app/src/gov/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #000000 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/icon_shield_access_white_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/drawable-xxhdpi/icon_shield_access_white_full.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/icon_shield_internet_white_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/app/src/main/res/drawable-xxhdpi/icon_shield_internet_white_full.png -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/090-Settings.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/090-Settings.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/18.txt: -------------------------------------------------------------------------------- 1 | * fix 'certificate expired' popup loop (issue #329) 2 | * add fastlane for F-Droid/Google Play release automation 3 | * update discovery signing keys 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/31.txt: -------------------------------------------------------------------------------- 1 | - update WireGuard, OpenVPN and "common" sub-modules 2 | - Move backend methods to background threads 3 | - More crash fixes 4 | - small README updates 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/080-ConnectionInfo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/080-ConnectionInfo.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/14.txt: -------------------------------------------------------------------------------- 1 | * Update ics-openvpn 2 | * Reduce size of app (do not add all static libs) 3 | * Add additional public keys for eduVPN discovery 4 | * Add application tests 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/011-FirstScreenNthUse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/011-FirstScreenNthUse.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/24.txt: -------------------------------------------------------------------------------- 1 | * Use common Go library for interfacing with VPN servers 2 | * Add govVPN flavor 3 | * Update dependencies 4 | * Added Catalan translation 5 | * Various bug fixes 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/010-FirstScreenFirstUse.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/010-FirstScreenFirstUse.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/030-ServerSearchResults.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/030-ServerSearchResults.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/050-ConnectedToSecureInternet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/050-ConnectedToSecureInternet.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/040-ConnectingToSecureInternet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/040-ConnectingToSecureInternet.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/061-ConnectedToInstituteAccess.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/061-ConnectedToInstituteAccess.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/031-ServerSearchResultsWith2dots.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/031-ServerSearchResultsWith2dots.jpg -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/images/phoneScreenshots/070-NotConnectedToSecureInternet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eduvpn/android/HEAD/fastlane/metadata/android/en-US/images/phoneScreenshots/070-NotConnectedToSecureInternet.jpg -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/livedata/IPs.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.livedata 2 | 3 | data class IPs(val clientIpv4: String?, val clientIpv6: String?, val tunnelData: TunnelData?) 4 | data class TunnelData(val tunnelIp: String?, val mtu: Int?) -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/19.txt: -------------------------------------------------------------------------------- 1 | * add support for APIv3 2 | * add support for WireGuard in combination with eduVPN/Let's Connect! 3.x servers 3 | * improve expiry notification 4 | * allow user to request a new session 5 | * update ics-openvpn 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/20.txt: -------------------------------------------------------------------------------- 1 | * add support for APIv3 2 | * add support for WireGuard in combination with eduVPN/Let's Connect! 3.x servers 3 | * improve expiry notification 4 | * allow user to request a new session 5 | * update ics-openvpn 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/full_description.txt: -------------------------------------------------------------------------------- 1 | eduVPN enables students, employees and researchers to connect securely and encrypted to the Internet. eduVPN integrates with the institutional network so that internal ICT services can be made available in a secure manner. 2 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/dialog_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/13.txt: -------------------------------------------------------------------------------- 1 | * Redesigned the entire app 2 | * Search for your organization or add your own server 3 | * Update ics-openvpn to version v0.7.17a 4 | * Added support for certificate expiry notifications 5 | * Your added servers are now grouped by type 6 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/27.txt: -------------------------------------------------------------------------------- 1 | - Update eduvpn-common to release 2.0.2 2 | - Implement support for ProxyGuard (WireGuard over TCP) 3 | - Fix "Country Switcher" 4 | - Improve error dialogs 5 | - Do not crash on invalid WireGuard configuration files 6 | - Update ics-openvpn (v0.7.5.1) 7 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/utils/Listener.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.utils 2 | 3 | interface Listener { 4 | /** 5 | * @param o the object calling `update` 6 | * @param arg an optional argument 7 | * method. 8 | */ 9 | fun update(o: Any, arg: Any?) 10 | } 11 | -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/gov/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/home/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/loading_gradient.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /app/src/home/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/VPNConfig.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.entity 2 | 3 | import com.wireguard.config.Config 4 | import de.blinkt.openvpn.VpnProfile 5 | 6 | sealed class VPNConfig { 7 | 8 | data class OpenVPN(val profile: VpnProfile) : VPNConfig() 9 | 10 | data class WireGuard(val config: Config) : VPNConfig() 11 | } 12 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/9.txt: -------------------------------------------------------------------------------- 1 | * Fix Gradle build 2 | * Immediately show "add provider" page when starting the app and no providers were added before for Let's Connect! flavor 3 | * Show "Profiles" instead of "Institute Access" for Let's Connect! flavor 4 | * Use different "certificate name" through API for eduVPN / Let's Connect! flavor 5 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ics-openvpn"] 2 | path = ics-openvpn 3 | url = https://codeberg.org/eduVPN/ics-openvpn 4 | [submodule "common/libs/eduvpn-common"] 5 | path = common/libs/eduvpn-common 6 | url = https://github.com/eduvpn/eduvpn-common 7 | [submodule "wireguard"] 8 | path = wireguard 9 | url = https://codeberg.org/eduVPN/wireguard-android 10 | -------------------------------------------------------------------------------- /common/src/main/java/org/eduvpn/common/ServerType.java: -------------------------------------------------------------------------------- 1 | package org.eduvpn.common; 2 | 3 | public enum ServerType { 4 | Unknown(0), 5 | InstituteAccess(1), 6 | SecureInternet(2), 7 | Custom(3); 8 | public final Integer nativeValue; 9 | ServerType(Integer nativeValue) { 10 | this.nativeValue = nativeValue; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/exception/ExceptionMessage.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.entity.exception 2 | 3 | import kotlinx.serialization.Serializable 4 | import nl.eduvpn.app.entity.TranslatableString 5 | 6 | @Serializable 7 | data class ExceptionMessage( 8 | val message: TranslatableString? = null, 9 | val misc: Boolean? = false 10 | ) 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/interpolator/progress_indeterminate_horizontal_rect1_scalex.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/28.txt: -------------------------------------------------------------------------------- 1 | - Custom tabs will be always on, remove the option 2 | - Move prefer TCP from a setting to a button 3 | - Sort country selector by country name 4 | - Display WireGuard (TCP) if connected with ProxyGuard 5 | - Fix connection state dialog staying on screen 6 | - Fix missing server name 7 | - Error handling for no connection case 8 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/CookieAndStringData.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.entity 2 | 3 | import kotlinx.serialization.Serializable 4 | 5 | @Serializable 6 | data class CookieAndStringData( 7 | val data: String, 8 | val cookie: Int 9 | ) 10 | 11 | @Serializable 12 | data class CookieAndStringArrayData( 13 | val data: List, 14 | val cookie: Int 15 | ) -------------------------------------------------------------------------------- /app/src/main/res/interpolator/progress_indeterminate_horizontal_rect1_translatex.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/delete_icon.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/interpolator/progress_indeterminate_horizontal_rect2_translatex.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /common/src/main/java/org/eduvpn/common/Protocol.java: -------------------------------------------------------------------------------- 1 | package org.eduvpn.common; 2 | 3 | public enum Protocol { 4 | Unknown(0), 5 | OpenVPN(1), 6 | WireGuard(2), 7 | WireGuardWithTCP(3), 8 | OpenVPNWithTCP(100); // Using number 100 here because it has no mapping in common 9 | 10 | 11 | public final Integer nativeValue; 12 | Protocol(Integer nativeValue) { 13 | this.nativeValue = nativeValue; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/Profile.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.entity 2 | 3 | import android.os.Parcelable 4 | import kotlinx.parcelize.Parcelize 5 | import kotlinx.serialization.SerialName 6 | import kotlinx.serialization.Serializable 7 | 8 | @Serializable 9 | @Parcelize 10 | data class Profile ( 11 | 12 | @SerialName("profile_id") 13 | val profileId: String, 14 | 15 | @SerialName("display_name") 16 | val displayName: TranslatableString, 17 | ) : Parcelable 18 | -------------------------------------------------------------------------------- /app/src/main/res/interpolator/progress_indeterminate_horizontal_rect2_scalex.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /common/src/main/java/org/eduvpn/common/DataErrorTuple.java: -------------------------------------------------------------------------------- 1 | package org.eduvpn.common; 2 | 3 | import androidx.annotation.Nullable; 4 | 5 | public class DataErrorTuple { 6 | public final @Nullable String data; 7 | public final @Nullable String error; 8 | 9 | DataErrorTuple(@Nullable String data, @Nullable String error) { 10 | this.data = data; 11 | this.error = error; 12 | } 13 | public boolean isError() { 14 | return error != null; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/exception/EduVPNException.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.entity.exception 2 | 3 | import androidx.annotation.StringRes 4 | 5 | /** 6 | * Exception with translatable message. 7 | * 8 | * @param formatArgs Arguments for [resourceIdMessage] 9 | */ 10 | class EduVPNException( 11 | @StringRes val resourceIdTitle: Int, 12 | @StringRes val resourceIdMessage: Int, 13 | vararg formatArgs: Any? 14 | ) : Exception() { 15 | val formatArgs = formatArgs 16 | } 17 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/6.txt: -------------------------------------------------------------------------------- 1 | * Update ics-openvpn submodule to v0.7.5 2 | * Update client_id 3 | * Fetch update server VPN configuration on connect 4 | * Fetch new client certificate if the old one expired 5 | * Fix connecting to 2FA enabled profile 6 | * Trigger new authorization on profiles page when OAuth client was revoked 7 | * Many text changes in the application 8 | * Initial Let's Connect! branding changes, still WiP 9 | * Fix use of "refresh token" 10 | * Update VPN connection status icon to new artwork 11 | -------------------------------------------------------------------------------- /common/src/main/java/org/eduvpn/common/FailoverResult.java: -------------------------------------------------------------------------------- 1 | package org.eduvpn.common; 2 | 3 | import androidx.annotation.Nullable; 4 | 5 | public class FailoverResult { 6 | public final boolean doesRequireFailover; 7 | public final @Nullable String error; 8 | 9 | FailoverResult(boolean doesRequireFailover, @Nullable String error) { 10 | this.doesRequireFailover = doesRequireFailover; 11 | this.error = error; 12 | } 13 | public boolean isError() { 14 | return error != null; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/utils/WireGuardTunnel.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.utils 2 | 3 | import com.wireguard.android.backend.Tunnel 4 | 5 | class WireGuardTunnel( 6 | private val name: String, 7 | private val onStateChangeFunction: (newState: Tunnel.State) -> Unit 8 | ) : Tunnel { 9 | 10 | override fun getName() = name 11 | 12 | var state: Tunnel.State = Tunnel.State.DOWN 13 | private set 14 | 15 | override fun onStateChange(newState: Tunnel.State) { 16 | state = newState 17 | onStateChangeFunction(newState) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/CertExpiryTimes.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.entity 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class CertExpiryTimes( 8 | @SerialName("start_time") 9 | val startTime: Long? = null, 10 | @SerialName("end_time") 11 | val endTime: Long? = null, 12 | @SerialName("button_time") 13 | val buttonTime: Long? = null, 14 | @SerialName("countdown_time") 15 | val countdownTime: Long? = null, 16 | @SerialName("notification_times") 17 | val notificationTimes: List = emptyList(), 18 | ) -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/viewmodel/ApiLogsViewModel.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.viewmodel 2 | 3 | import androidx.lifecycle.AndroidViewModel 4 | import androidx.lifecycle.ViewModel 5 | import nl.eduvpn.app.service.BackendService 6 | import nl.eduvpn.app.service.HistoryService 7 | import nl.eduvpn.app.service.PreferencesService 8 | import javax.inject.Inject 9 | 10 | class ApiLogsViewModel @Inject constructor( 11 | private val backendService: BackendService 12 | ) : ViewModel() { 13 | fun getLogFileContents() : String { 14 | return backendService.getLogFile()!!.readLines().joinToString("\n") 15 | } 16 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # This will allow us to get the correct file line numbers to the errors 2 | -keepattributes SourceFile,LineNumberTable 3 | 4 | -dontwarn com.google.errorprone.annotations.* 5 | -dontwarn org.bouncycastle.jsse.** 6 | -dontwarn org.conscrypt.* 7 | -dontwarn org.openjsse.javax.net.ssl.* 8 | -dontwarn org.openjsse.net.ssl.* 9 | 10 | -keepclassmembers class com.wireguard.android.backend.GoBackend { 11 | ; 12 | } 13 | -keepclassmembers class com.wireguard.android.backend.GoBackend$GhettoCompletableFuture { 14 | ; 15 | } 16 | -keepclassmembers class android.net.VpnService { 17 | ; 18 | } -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/SerializedVpnConfig.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.entity 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | import org.eduvpn.common.Protocol 6 | 7 | @Serializable 8 | data class SerializedVpnConfig( 9 | val config: String, 10 | val protocol: Int, 11 | @SerialName("default_gateway") 12 | val defaultGateway: Boolean, 13 | @SerialName("should_failover") 14 | val shouldFailover: Boolean = false, 15 | val proxy: ProxySettings? = null 16 | ) 17 | 18 | @Serializable 19 | data class ProxySettings( 20 | @SerialName("source_port") 21 | val sourcePort: Int, 22 | val listen: String, 23 | val peer: String 24 | ) -------------------------------------------------------------------------------- /app/src/main/res/drawable/button_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /create_release_tar.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | GIT_REPO=https://codeberg.org/eduVPN/android 4 | GIT_TAG=3.3.4 5 | #GIT_TAG=master 6 | 7 | ############################################################################### 8 | # CLONE 9 | ############################################################################### 10 | 11 | ( 12 | mkdir -p release 13 | cd release || exit 14 | 15 | git clone --recursive -b ${GIT_TAG} ${GIT_REPO} eduvpn-android-${GIT_TAG} 16 | 17 | ( 18 | cd eduvpn-android-${GIT_TAG} || exit 19 | # remove all ".git" folders 20 | find . -type d -name ".git" | xargs rm -rf 21 | ) 22 | 23 | tar -cJf eduvpn-android-${GIT_TAG}.tar.xz eduvpn-android-${GIT_TAG} 24 | rm -rf eduvpn-android-${GIT_TAG} 25 | minisign -Sm eduvpn-android-${GIT_TAG}.tar.xz 26 | ) 27 | -------------------------------------------------------------------------------- /common/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /app/src/main/res/anim/progress_indeterminate_horizontal_rect1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/dialog_button_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 10 | 11 | 12 | 13 | 14 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /NEW_RELEASE.md: -------------------------------------------------------------------------------- 1 | # Tag a Release 2 | 3 | Walk through the following steps when making a new release: 4 | 5 | * Update `CHANGES.md` to make sure all changes are recorded for the new release 6 | including the release date, e.g.: `3.2.0 (2023-12-22)`; 7 | * Increment the `versionCode` and set `versionName` to the correct version tag 8 | in `app/build.gradle`; 9 | * Copy the entries from the `CHANGES.md` file you made also to 10 | `fastlane/metadata/android/en-US/changelogs/$versionCode.txt`; 11 | * Update the `build_app_git.sh`, `build_app_tar.sh`, `create_release_tar.sh`, 12 | and if necessary `builder_setup.sh`; 13 | * Create an "annotated" tag with e.g. `git tag 3.2.0 -a -m '3.2.0'`; 14 | * Push the tag, e.g.: `git push origin 3.2.0`; 15 | * Create a release with `create_release_tar.sh` and "attach" the `.tar.xz` and 16 | `.tar.xz.minisig` files to the release on the forge 17 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/utils/serializer/DateSerializer.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.utils.serializer 2 | 3 | import kotlinx.serialization.KSerializer 4 | import kotlinx.serialization.descriptors.PrimitiveKind 5 | import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor 6 | import kotlinx.serialization.descriptors.SerialDescriptor 7 | import kotlinx.serialization.encoding.Decoder 8 | import kotlinx.serialization.encoding.Encoder 9 | import java.util.* 10 | 11 | object DateSerializer : KSerializer { 12 | 13 | override val descriptor: SerialDescriptor = 14 | PrimitiveSerialDescriptor("Date", PrimitiveKind.LONG) 15 | 16 | override fun serialize(encoder: Encoder, value: Date) { 17 | encoder.encodeLong(value.time) 18 | } 19 | 20 | override fun deserialize(decoder: Decoder): Date { 21 | return Date(decoder.decodeLong()) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/res/anim/progress_indeterminate_horizontal_rect2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 17 | 18 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/viewmodel/SettingsViewModel.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.viewmodel 2 | 3 | import androidx.lifecycle.AndroidViewModel 4 | import androidx.lifecycle.ViewModel 5 | import androidx.lifecycle.viewModelScope 6 | import kotlinx.coroutines.Dispatchers 7 | import kotlinx.coroutines.launch 8 | import nl.eduvpn.app.service.BackendService 9 | import nl.eduvpn.app.service.HistoryService 10 | import javax.inject.Inject 11 | 12 | class SettingsViewModel @Inject constructor( 13 | private val historyService: HistoryService, 14 | private val backendService: BackendService 15 | ) : ViewModel() { 16 | 17 | val apiLogFile get() = backendService.getLogFile() 18 | 19 | val hasAddedServers get() = historyService.addedServers?.hasServers() == true 20 | 21 | fun removeOrganizationData() { 22 | viewModelScope.launch(Dispatchers.IO) { 23 | historyService.removeOrganizationData() 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /app/src/gov/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | govVPN 20 | govVPN 21 | 22 | -------------------------------------------------------------------------------- /app/src/dev/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | eduVPN (dev) 20 | eduVPN (dev) 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/values/ids.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/DisconnectVPNBroadcastReceiver.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app 2 | 3 | import android.content.BroadcastReceiver 4 | import android.content.Context 5 | import android.content.Intent 6 | import nl.eduvpn.app.service.VPNConnectionService 7 | import nl.eduvpn.app.service.VPNService 8 | import javax.inject.Inject 9 | 10 | class DisconnectVPNBroadcastReceiver : BroadcastReceiver() { 11 | 12 | @Inject 13 | protected lateinit var vpnConnectionService: VPNConnectionService 14 | 15 | @Inject 16 | protected lateinit var vpnService: VPNService 17 | 18 | companion object { 19 | val ACTION = this::class.qualifiedName!!.plus(".disconnect_vpn") 20 | } 21 | 22 | override fun onReceive(context: Context, intent: Intent) { 23 | EduVPNApplication.get(context).component().inject(this) 24 | if (intent.action != ACTION) { 25 | return 26 | } 27 | vpnConnectionService.disconnect(context, vpnService) 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/exception/CommonException.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.entity.exception 2 | 3 | import kotlinx.serialization.decodeFromString 4 | import kotlinx.serialization.json.Json 5 | 6 | data class CommonException(override val message: String?) : Exception(message) { 7 | 8 | private val exceptionMessage: ExceptionMessage? get() { 9 | if (message == null) { 10 | return null 11 | } 12 | return try { 13 | json.decodeFromString(message) 14 | } catch (ex: Exception) { 15 | null 16 | } 17 | } 18 | 19 | fun translatedMessage() : String { 20 | if (message == null) { 21 | return toString() 22 | } 23 | return exceptionMessage?.message?.bestTranslation ?: message 24 | } 25 | 26 | fun isMiscError(): Boolean { 27 | return exceptionMessage?.misc == true 28 | } 29 | 30 | companion object { 31 | private val json = Json { ignoreUnknownKeys = true } 32 | } 33 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_search.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 17 | 18 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /fastlane/metadata/android/en-US/changelogs/10.txt: -------------------------------------------------------------------------------- 1 | * Updated the flow: instead of profiles you now select servers first. We don't connect to each server to fetch the latest profiles. 2 | * Added some animations and updated loading indicators for a smoother user experience. 3 | * You can remove servers by long pressing on them, instead of swiping. 4 | * Update ics-openvpn submodule to v0.7.10 (#188). This adds support for TLSv1.3, Ed25519 keys, and includes OpenSSL 1.1.1d. 5 | * Redirect URLs are now followed. 6 | * Android 10 support, also updated most of our libraries to their latest version. 7 | * Added license screen. 8 | * Fixed some edge-cases where IPv4 / IPv6 / Duration would not be displayed when connected, and the back button would not appear. 9 | * When connecting, the notifications tab is only shown when there are any notifications. 10 | * Fixed a crash which happened on screen rotation. 11 | * Removed mentions of 2FA. 12 | * Deprecated the secure-preferences library, added migration. 13 | * Updated documentations and build scripts. 14 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/CookieAndProfileMapData.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.entity 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | 6 | @Serializable 7 | data class CookieAndProfileMapData( 8 | val data: ProfileWithoutIdMap, 9 | val cookie: Int 10 | ) 11 | 12 | @Serializable 13 | data class ProfileWithoutIdMap( 14 | internal val map: Map? = null, 15 | @SerialName("current") 16 | internal val currentProfileId: String? 17 | ) { 18 | fun getProfileList(): List { 19 | return map?.map { 20 | Profile( 21 | profileId = it.key, 22 | displayName = it.value.displayName, 23 | ) 24 | } ?: emptyList() 25 | } 26 | 27 | val currentProfile: Profile? = getProfileList().firstOrNull { it.profileId == currentProfileId } 28 | } 29 | 30 | @Serializable 31 | data class ProfileWithoutId( 32 | @SerialName("display_name") 33 | val displayName: TranslatableString, 34 | ) -------------------------------------------------------------------------------- /app/src/main/res/anim/fade_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/ServerList.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | * 17 | */ 18 | 19 | package nl.eduvpn.app.entity 20 | 21 | import kotlinx.serialization.SerialName 22 | import kotlinx.serialization.Serializable 23 | 24 | /** 25 | * A versioned list of organizations 26 | */ 27 | @Serializable 28 | data class ServerList( 29 | @SerialName("server_list") 30 | val serverList: List? = null 31 | ) 32 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/scrollbar_thumb.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/OrganizationList.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | * 17 | */ 18 | 19 | package nl.eduvpn.app.entity 20 | 21 | import kotlinx.serialization.SerialName 22 | import kotlinx.serialization.Serializable 23 | 24 | /** 25 | * A versioned list of organizations 26 | */ 27 | @Serializable 28 | data class OrganizationList( 29 | @SerialName("organization_list") 30 | val organizationList: List? = null 31 | ) -------------------------------------------------------------------------------- /app/src/main/res/color/bg_big_button.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 80dp 3 | 40dp 4 | 5 | 48dp 6 | 32dp 7 | 8 | 56dp 9 | 64dp 10 | 11 | 20sp 12 | 16dp 13 | 32dp 14 | 32dp 15 | 120dp 16 | 80dp 17 | 4dp 18 | 12dp 19 | 16dp 20 | 40dp 21 | 15sp 22 | 24dp 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/access_type_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_chevron_right.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | org.gradle.jvmargs=-Xmx1536M 20 | 21 | android.useAndroidX=true 22 | android.enableJetifier=true 23 | android.defaults.buildfeatures.buildconfig=true 24 | 25 | wireguardPackageName=com.wireguard 26 | wireguardVersionName=1.0.20231018-eduvpn-fork -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/inject/ViewModelKey.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | * 17 | */ 18 | 19 | package nl.eduvpn.app.inject 20 | 21 | import androidx.lifecycle.ViewModel 22 | import dagger.MapKey 23 | import kotlin.reflect.KClass 24 | 25 | @MapKey 26 | @MustBeDocumented 27 | @Retention(AnnotationRetention.RUNTIME) 28 | @Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER) 29 | annotation class ViewModelKey(val value: KClass) -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_add.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 25 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_arrow_drop_down.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 25 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_warning.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/switch_thumb.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_institute.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/Organization.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | * 17 | */ 18 | 19 | package nl.eduvpn.app.entity 20 | 21 | import kotlinx.serialization.SerialName 22 | import kotlinx.serialization.Serializable 23 | 24 | @Serializable 25 | data class Organization( 26 | @SerialName("org_id") 27 | val orgId: String, 28 | @SerialName("display_name") 29 | val displayName: TranslatableString = TranslatableString(), 30 | @SerialName("keyword_list") 31 | val keywordList: TranslatableString = TranslatableString(), 32 | ) -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_progressbar_indeterminate.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 21 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | // The following block is needed because of this issue: https://stackoverflow.com/a/76954759/1395437 2 | // Can be removed when upgrading to Android Studio Hedgehog 3 | pluginManagement { 4 | repositories { 5 | gradlePluginPortal() 6 | google() 7 | mavenCentral() 8 | 9 | } 10 | } 11 | 12 | dependencyResolutionManagement { 13 | repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) 14 | repositories { 15 | gradlePluginPortal() 16 | google() 17 | mavenCentral() 18 | jcenter() 19 | maven { 20 | url = uri("https://jitpack.io") 21 | } 22 | } 23 | versionCatalogs { 24 | libVersions { 25 | from(files('ics-openvpn/gradle/libs.versions.toml')) 26 | } 27 | eduvpnVersions { 28 | from(files('gradle/libs.versions.toml')) 29 | } 30 | wireguardVersions { 31 | from(files('wireguard/gradle/libs.versions.toml')) 32 | } 33 | } 34 | } 35 | 36 | include ':app' 37 | include ':ics-openvpn-main' 38 | project(':ics-openvpn-main').projectDir = new File(rootDir, '/ics-openvpn/main') 39 | include ':common' 40 | include ':wireguard' 41 | project(':wireguard').projectDir = new File(rootDir, '/wireguard/tunnel') 42 | -------------------------------------------------------------------------------- /app/src/home/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | Let\'s Connect! 20 | Let\'s Connect! 21 | Add Provider 22 | Servers 23 | 27 | Profiles 28 | 29 | -------------------------------------------------------------------------------- /app/src/home/res/values-de/strings.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | Let\'s Connect! 20 | Let\'s Connect! 21 | Anbieter hinzufügen 22 | Server 23 | 27 | Profile 28 | 29 | -------------------------------------------------------------------------------- /app/src/home/res/values-es/strings.xml: -------------------------------------------------------------------------------- 1 | 17 | 18 | 19 | Let\'s Connect! 20 | Let\'s Connect! 21 | Agregar Proveedor 22 | Servidores 23 | 27 | Perfiles 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/AuthorizationType.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | */ 17 | 18 | package nl.eduvpn.app.entity 19 | 20 | import kotlinx.serialization.SerialName 21 | import kotlinx.serialization.Serializable 22 | 23 | /** 24 | * The type of the VPN which the user will connect to. 25 | * Created by Daniel Zolnai on 2017-07-31. 26 | */ 27 | @Serializable 28 | enum class AuthorizationType { 29 | 30 | @SerialName("institute_access") 31 | Local, 32 | 33 | @SerialName("secure_internet") 34 | Distributed, 35 | 36 | @SerialName("organization") 37 | Organization 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/viewmodel/ProfileSelectionViewModel.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | * 17 | */ 18 | 19 | package nl.eduvpn.app.viewmodel 20 | 21 | import android.content.Context 22 | import nl.eduvpn.app.service.* 23 | import javax.inject.Inject 24 | 25 | class ProfileSelectionViewModel @Inject constructor( 26 | context: Context, 27 | historyService: HistoryService, 28 | preferencesService: PreferencesService, 29 | backendService: BackendService, 30 | vpnConnectionService: VPNConnectionService, 31 | ) : BaseConnectionViewModel( 32 | context, 33 | backendService, 34 | historyService, 35 | preferencesService, 36 | vpnConnectionService, 37 | ) 38 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/viewmodel/ConnectionState.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | * 17 | */ 18 | 19 | package nl.eduvpn.app.viewmodel 20 | 21 | import androidx.annotation.StringRes 22 | import nl.eduvpn.app.R 23 | 24 | enum class ConnectionState(@StringRes val displayString: Int?) { 25 | Ready(null), 26 | FetchingOrganizations(R.string.fetching_organization_servers), 27 | FetchingServerList(R.string.fetching_server_list), 28 | DiscoveringApi(R.string.api_discovery_message), 29 | FetchingProfiles(R.string.loading_available_profiles), 30 | Authorizing(R.string.loading_browser_for_authorization), 31 | ProfileDownloadingKeyPair(R.string.vpn_profile_creating_keypair) 32 | } 33 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_vpn_profile.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/base/BaseActivity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | * 17 | */ 18 | 19 | package nl.eduvpn.app.base 20 | 21 | import android.os.Bundle 22 | import androidx.annotation.LayoutRes 23 | import androidx.appcompat.app.AppCompatActivity 24 | import androidx.databinding.DataBindingUtil 25 | import androidx.databinding.ViewDataBinding 26 | 27 | abstract class BaseActivity : AppCompatActivity() { 28 | 29 | protected lateinit var binding: B 30 | 31 | @get:LayoutRes 32 | protected abstract val layout: Int 33 | 34 | override fun onCreate(savedInstanceState: Bundle?) { 35 | super.onCreate(savedInstanceState) 36 | binding = DataBindingUtil.setContentView(this, layout) 37 | binding.lifecycleOwner = this 38 | } 39 | 40 | 41 | } -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/livedata/openvpn/ByteCountLiveData.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | */ 17 | 18 | package nl.eduvpn.app.livedata.openvpn 19 | 20 | import androidx.lifecycle.LiveData 21 | import de.blinkt.openvpn.core.VpnStatus 22 | import nl.eduvpn.app.livedata.ByteCount 23 | 24 | class ByteCountLiveData : LiveData() { 25 | 26 | private val byteCountListener: VpnStatus.ByteCountListener = 27 | VpnStatus.ByteCountListener { inBytes, outBytes, _, _ -> 28 | postValue(ByteCount(inBytes, outBytes)) 29 | } 30 | 31 | override fun onActive() { 32 | VpnStatus.addByteCountListener(byteCountListener) 33 | } 34 | 35 | override fun onInactive() { 36 | VpnStatus.removeByteCountListener(byteCountListener) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /common/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | alias(libVersions.plugins.android.library) 3 | } 4 | 5 | android { 6 | namespace 'org.eduvpn.common' 7 | compileSdk 33 8 | ndkVersion = "26.1.10909125" 9 | 10 | def commonVersion = "2.0.0" 11 | 12 | defaultConfig { 13 | minSdk 21 14 | 15 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 16 | consumerProguardFiles "consumer-rules.pro" 17 | externalNativeBuild { 18 | cmake { 19 | cppFlags "" 20 | } 21 | } 22 | 23 | buildConfigField "String", "COMMON_VERSION", "\"$commonVersion\"" 24 | } 25 | 26 | buildTypes { 27 | release { 28 | minifyEnabled false 29 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 30 | } 31 | } 32 | externalNativeBuild { 33 | cmake { 34 | path "libs/CMakeLists.txt" 35 | } 36 | } 37 | compileOptions { 38 | sourceCompatibility JavaVersion.VERSION_1_8 39 | targetCompatibility JavaVersion.VERSION_1_8 40 | } 41 | buildTypes { 42 | configureEach { 43 | externalNativeBuild { 44 | cmake { 45 | targets("libeduvpn_common", "eduvpn_common-wrapper") 46 | arguments("-DCOMMON_VERSION=$commonVersion") 47 | } 48 | } 49 | } 50 | } 51 | } 52 | 53 | dependencies { 54 | implementation 'androidx.annotation:annotation-jvm:1.7.0' 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/Constants.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | */ 17 | package nl.eduvpn.app 18 | 19 | import android.net.Uri 20 | import java.util.* 21 | 22 | /** 23 | * Contains application-wide constant values. 24 | * Created by Daniel Zolnai on 2016-09-14. 25 | */ 26 | object Constants { 27 | @JvmField 28 | val DEBUG = BuildConfig.BUILD_TYPE.equals("debug", ignoreCase = true) 29 | 30 | @JvmField 31 | val LOCALE = Locale.getDefault() 32 | val ENGLISH_LOCALE = Locale.ENGLISH 33 | 34 | const val SERVER_LIST_VALID_FOR_MS: Long = 3600000 // 1 hour 35 | 36 | const val CERT_EXPIRY_NOTIFICATION_CHANNEL_ID = "cert_expiry" 37 | const val CERT_EXPIRY_NOTIFICATION_ID = 1 38 | 39 | const val VPN_CONNECTION_NOTIFICATION_CHANNEL_ID = "vpn_connection" 40 | const val VPN_CONNECTION_NOTIFICATION_ID = 2 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_openvpn_logs.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 26 | 27 | 32 | 33 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/ApiLogsActivity.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app 2 | 3 | import android.os.Bundle 4 | import android.view.MenuItem 5 | import androidx.activity.viewModels 6 | import androidx.core.view.isVisible 7 | import nl.eduvpn.app.base.BaseActivity 8 | import nl.eduvpn.app.databinding.ActivityApiLogsBinding 9 | import nl.eduvpn.app.viewmodel.ApiLogsViewModel 10 | import nl.eduvpn.app.viewmodel.ViewModelFactory 11 | import javax.inject.Inject 12 | 13 | class ApiLogsActivity : BaseActivity() { 14 | 15 | override val layout = R.layout.activity_api_logs 16 | 17 | @Inject 18 | protected lateinit var viewModelFactory: ViewModelFactory 19 | 20 | private val viewModel by viewModels { viewModelFactory } 21 | override fun onCreate(savedInstanceState: Bundle?) { 22 | super.onCreate(savedInstanceState) 23 | EduVPNApplication.get(this).component().inject(this) 24 | setSupportActionBar(binding.toolbar.toolbar) 25 | supportActionBar?.setDisplayHomeAsUpEnabled(true) 26 | binding.toolbar.settingsButton.isVisible = false 27 | 28 | } 29 | 30 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 31 | return if (item.itemId == android.R.id.home) { 32 | onBackPressedDispatcher.onBackPressed() 33 | true 34 | } else { 35 | super.onOptionsItemSelected(item) 36 | } 37 | } 38 | 39 | override fun onResume() { 40 | super.onResume() 41 | binding.logContents.text = viewModel.getLogFileContents() 42 | } 43 | } -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/service/VPNService.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.service 2 | 3 | import android.app.Notification 4 | import androidx.lifecycle.LiveData 5 | import kotlinx.coroutines.flow.Flow 6 | import nl.eduvpn.app.livedata.ByteCount 7 | import nl.eduvpn.app.livedata.IPs 8 | import org.eduvpn.common.Protocol 9 | 10 | abstract class VPNService : LiveData() { 11 | 12 | enum class VPNStatus { 13 | DISCONNECTED, CONNECTING, CONNECTED, PAUSED, FAILED 14 | } 15 | 16 | abstract val byteCountFlow: Flow 17 | 18 | abstract val ipFlow: Flow 19 | 20 | /** 21 | * User should call this after showing a notification. 22 | * 23 | * @param id The identifier for this notification as per 24 | * {@link NotificationManager#notify(int, Notification) 25 | * NotificationManager.notify(int, Notification)}; 26 | * @param notification The Notification to be displayed. 27 | */ 28 | abstract fun startForeground(id: Int, notification: Notification) 29 | 30 | /** 31 | * Disconnects the current VPN connection. 32 | */ 33 | abstract fun disconnect() 34 | 35 | /** 36 | * Returns the error string. 37 | * 38 | * @return The description of the error. 39 | */ 40 | abstract fun getErrorString(): String? 41 | 42 | /** 43 | * @return The current status of the VPN. 44 | */ 45 | abstract fun getStatus(): VPNStatus 46 | 47 | /** 48 | * Type of the VPN protocol this service implements. 49 | */ 50 | abstract fun getProtocol(): Protocol 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/OpenVpnLogsActivity.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app 2 | 3 | import android.os.Bundle 4 | import android.view.MenuItem 5 | import androidx.activity.viewModels 6 | import androidx.core.view.isVisible 7 | import de.blinkt.openvpn.fragments.LogFragment 8 | import nl.eduvpn.app.base.BaseActivity 9 | import nl.eduvpn.app.databinding.ActivityApiLogsBinding 10 | import nl.eduvpn.app.databinding.ActivityOpenvpnLogsBinding 11 | import nl.eduvpn.app.viewmodel.ApiLogsViewModel 12 | import nl.eduvpn.app.viewmodel.ViewModelFactory 13 | import javax.inject.Inject 14 | 15 | class OpenVpnLogsActivity : BaseActivity() { 16 | 17 | override val layout = R.layout.activity_openvpn_logs 18 | 19 | @Inject 20 | protected lateinit var viewModelFactory: ViewModelFactory 21 | 22 | override fun onCreate(savedInstanceState: Bundle?) { 23 | super.onCreate(savedInstanceState) 24 | EduVPNApplication.get(this).component().inject(this) 25 | setSupportActionBar(binding.toolbar.toolbar) 26 | supportActionBar?.setDisplayHomeAsUpEnabled(true) 27 | binding.toolbar.settingsButton.isVisible = false 28 | supportFragmentManager.beginTransaction() 29 | .add(binding.fragmentContainer.id, LogFragment()) 30 | .commit() 31 | } 32 | 33 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 34 | return if (item.itemId == android.R.id.home) { 35 | onBackPressedDispatcher.onBackPressed() 36 | true 37 | } else { 38 | super.onOptionsItemSelected(item) 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_licenses.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 26 | 27 | 33 | 34 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/viewmodel/AddServerViewModel.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | * 17 | */ 18 | 19 | package nl.eduvpn.app.viewmodel 20 | 21 | import android.content.Context 22 | import androidx.lifecycle.MutableLiveData 23 | import androidx.lifecycle.map 24 | import nl.eduvpn.app.service.* 25 | import javax.inject.Inject 26 | 27 | class AddServerViewModel @Inject constructor( 28 | preferencesService: PreferencesService, 29 | context: Context, 30 | historyService: HistoryService, 31 | backendService: BackendService, 32 | vpnConnectionService: VPNConnectionService, 33 | ) : BaseConnectionViewModel( 34 | context, 35 | backendService, 36 | historyService, 37 | preferencesService, 38 | vpnConnectionService, 39 | ) { 40 | 41 | val serverUrl = MutableLiveData("") 42 | 43 | val addButtonEnabled = serverUrl.map { url -> 44 | url != null && url.contains(".") && url.length > 3 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/res/values/content_description.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | Secure Internet 21 | Institute Access 22 | Connection status 23 | Provider icon 24 | Application logo 25 | Settings button 26 | Message icon 27 | Warning icon 28 | Expand / collapse arrow 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item_provider.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 19 | 20 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/androidTest/java/nl/eduvpn/app/UnitTestSuite.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | */ 17 | 18 | package nl.eduvpn.app; 19 | 20 | import nl.eduvpn.app.service.HistoryServiceTest; 21 | import nl.eduvpn.app.service.PreferencesServiceTest; 22 | import nl.eduvpn.app.service.SerializerServiceTest; 23 | import nl.eduvpn.app.utils.FormattingUtilsTest; 24 | 25 | import org.junit.runner.RunWith; 26 | import org.junit.runners.Suite; 27 | 28 | /** 29 | * Suite used to run all unit tests. 30 | * Created by Daniel Zolnai on 2016-10-18. 31 | */ 32 | @RunWith(Suite.class) 33 | @Suite.SuiteClasses({SerializerServiceTest.class, PreferencesServiceTest.class, 34 | HistoryServiceTest.class, FormattingUtilsTest.class}) 35 | public class UnitTestSuite { 36 | // Test suite used to run all unit tests at once. 37 | // To run the tests, right click on the class name, and select "Run 'UnitTestSuite'". 38 | // The tests will run on your device. 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/res/values-de/content_description.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | Sicheres Internet 21 | Organisations-Zugang 22 | Verbindungsstatus 23 | Anbieter-Symbol 24 | Anwendungs-Symbol 25 | Schaltfläche Einstellungen 26 | Nachrichten-Symbol 27 | Warnungs-Symbol 28 | Pfeil zum aus-/einklappen 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/values-ca/content_description.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | Secure Internet 21 | Access Institucional 22 | Estat de la Connexió 23 | Icona del Proveïdor 24 | Logotip de l\'Aplicació 25 | Botó de Preferències 26 | Icona de Missatge 27 | Icona d\'Advertència 28 | Fletxa d\'expandir / colapsar 29 | -------------------------------------------------------------------------------- /app/src/main/res/values-es/content_description.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | Internet Seguro 21 | Acceso Institucional 22 | Estado de conexión 23 | Icono de proveedor 24 | Logo de aplicación 25 | Botón de configuraciones 26 | Icono de mensaje 27 | Icono de advertencia 28 | Flecha de expandir / colapsar 29 | 30 | -------------------------------------------------------------------------------- /app/src/androidTest/java/nl/eduvpn/app/utils/ParcelableTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | */ 17 | 18 | package nl.eduvpn.app.utils 19 | 20 | import android.os.Parcel 21 | import androidx.test.ext.junit.runners.AndroidJUnit4 22 | import nl.eduvpn.app.entity.TranslatableString 23 | import org.junit.Assert 24 | import org.junit.Test 25 | import org.junit.runner.RunWith 26 | 27 | @RunWith(AndroidJUnit4::class) 28 | class ParcelableTest { 29 | 30 | @Test 31 | fun testTranslatableStringParcelable() { 32 | val expected = TranslatableString( 33 | mapOf("en" to "Hello", "es" to "Hola", "nl" to "Hallo") 34 | ) 35 | val parcel = Parcel.obtain() 36 | expected.writeToParcel(parcel, 0) 37 | // Reset parcel for reading 38 | parcel.setDataPosition(0) 39 | val actual = TranslatableString.CREATOR.createFromParcel(parcel) 40 | parcel.recycle() 41 | Assert.assertEquals(expected, actual) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_secure_internet.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/home/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #1193F5 4 | #1193F5 5 | #0666AF 6 | #1193F5 7 | #1193F5 8 | #808080 9 | #101010 10 | #505050 11 | #FFFFFF 12 | #FFFFFF 13 | #101010 14 | #E0E0E0 15 | #FFFFFF 16 | #E9E9E9 17 | #D0D0D0 18 | #C0C0C0 19 | #00A2C8 20 | #505050 21 | #FFFFFF 22 | #CCCCCC 23 | #00FFFFFF 24 | #FFFFFF 25 | #216aed 26 | #7DA7F3 27 | #F0F0F0 28 | 29 | #16a566 30 | #b2b2b2 31 | #E4E4E4 32 | #FFFFFF 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #E24301 4 | #E24301 5 | #9A2E00 6 | #EC5D22 7 | #E24301 8 | #808080 9 | #101010 10 | #505050 11 | #FFFFFF 12 | #216aed 13 | #FFFFFF 14 | #101010 15 | #E0E0E0 16 | #FFFFFF 17 | #E9E9E9 18 | #D0D0D0 19 | #C0C0C0 20 | #00A2C8 21 | #505050 22 | #FFFFFF 23 | #CCCCCC 24 | #00FFFFFF 25 | #FFFFFF 26 | #216aed 27 | #7DA7F3 28 | #F0F0F0 29 | 30 | #16a566 31 | #b2b2b2 32 | #E4E4E4 33 | #FFFFFF 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/viewmodel/ViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | * 17 | */ 18 | 19 | package nl.eduvpn.app.viewmodel 20 | 21 | import androidx.lifecycle.ViewModel 22 | import androidx.lifecycle.ViewModelProvider 23 | import javax.inject.Inject 24 | import javax.inject.Provider 25 | 26 | /** 27 | * Factory for [ViewModel]'s 28 | */ 29 | class ViewModelFactory @Inject constructor( 30 | private val viewModelsMap: Map, @JvmSuppressWildcards Provider> 31 | ) : ViewModelProvider.Factory { 32 | override fun create(modelClass: Class): T { 33 | val creator = viewModelsMap[modelClass] 34 | ?: viewModelsMap.entries.firstOrNull { 35 | modelClass.isAssignableFrom(it.key) 36 | }?.value ?: throw IllegalArgumentException("Unknown ViewModel class $modelClass") 37 | 38 | return try { 39 | @Suppress("UNCHECKED_CAST") 40 | creator.get() as T 41 | } catch (e: Exception) { 42 | throw RuntimeException(e) 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/livedata/UnlessDisconnectedLiveData.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | */ 17 | 18 | package nl.eduvpn.app.livedata 19 | 20 | import androidx.lifecycle.LiveData 21 | import androidx.lifecycle.MediatorLiveData 22 | import nl.eduvpn.app.service.VPNService 23 | 24 | /** 25 | * Live data unless VPN disconnected. 26 | */ 27 | object UnlessDisconnectedLiveData { 28 | fun create( 29 | liveData: LiveData, 30 | vpnStatusLiveData: LiveData 31 | ): LiveData { 32 | val mediator = MediatorLiveData() 33 | mediator.addSource(liveData) { value -> 34 | mediator.value = if (vpnStatusLiveData.value == VPNService.VPNStatus.DISCONNECTED) { 35 | null 36 | } else { 37 | value 38 | } 39 | } 40 | mediator.addSource(vpnStatusLiveData) { vpnStatus -> 41 | if (vpnStatus == VPNService.VPNStatus.DISCONNECTED) { 42 | mediator.value = null 43 | } 44 | } 45 | return mediator 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/base/BaseFragment.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | * 17 | */ 18 | 19 | package nl.eduvpn.app.base 20 | 21 | import android.os.Bundle 22 | import android.view.LayoutInflater 23 | import android.view.View 24 | import android.view.ViewGroup 25 | import androidx.annotation.LayoutRes 26 | import androidx.databinding.DataBindingUtil 27 | import androidx.databinding.ViewDataBinding 28 | import androidx.fragment.app.Fragment 29 | import nl.eduvpn.app.viewmodel.ViewModelFactory 30 | import javax.inject.Inject 31 | 32 | abstract class BaseFragment : Fragment() { 33 | 34 | protected lateinit var binding: B 35 | 36 | @Inject 37 | protected lateinit var viewModelFactory : ViewModelFactory 38 | 39 | @get:LayoutRes 40 | protected abstract val layout: Int 41 | 42 | override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { 43 | binding = DataBindingUtil.inflate(inflater, layout, container, false).also { 44 | it.lifecycleOwner = this.viewLifecycleOwner 45 | } 46 | return binding.root 47 | } 48 | } -------------------------------------------------------------------------------- /app/src/main/res/anim/fade_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 37 | 43 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_server.xml: -------------------------------------------------------------------------------- 1 | 6 | 12 | 18 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/switch_track.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/home/res/drawable/ic_application_logo.xml: -------------------------------------------------------------------------------- 1 | 6 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_api_logs.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 20 | 26 | 27 | 33 | 34 | 41 | 42 | 43 | 44 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/adapter/viewholder/ProfileViewHolder.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | */ 17 | 18 | package nl.eduvpn.app.adapter.viewholder 19 | 20 | 21 | import android.text.TextUtils 22 | import androidx.recyclerview.widget.RecyclerView 23 | import com.squareup.picasso.Picasso 24 | import nl.eduvpn.app.R 25 | import nl.eduvpn.app.databinding.ListItemProfileBinding 26 | import nl.eduvpn.app.entity.Instance 27 | import nl.eduvpn.app.entity.Profile 28 | import nl.eduvpn.app.utils.FormattingUtils 29 | 30 | /** 31 | * View holder for the provider instance list. 32 | * Created by Daniel Zolnai on 2016-10-07. 33 | */ 34 | class ProfileViewHolder(private val binding: ListItemProfileBinding) : RecyclerView.ViewHolder(binding.root) { 35 | 36 | fun bind(instance: Instance, profile: Profile) { 37 | binding.profileName.text = profile.displayName.bestTranslation 38 | binding.profileProvider.text = FormattingUtils.formatDisplayName(instance) 39 | if (!TextUtils.isEmpty(instance.logoUri)) { 40 | Picasso.get() 41 | .load(instance.logoUri) 42 | .fit() 43 | .into(binding.profileIcon) 44 | } else { 45 | binding.profileIcon.setImageResource(R.drawable.ic_vpn_profile) 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /app/src/dev/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | #A0A0A0 21 | #A0A0A0 22 | #808080 23 | #FF9800 24 | #D0D0D0 25 | #FFFFFF 26 | #FFFFFF 27 | #808080 28 | #FF5722 29 | #000000 30 | #202020 31 | #C0C0C0 32 | #FFFFFF 33 | #CF0000 34 | #F0F0F0 35 | #00000000 36 | #000000 37 | #FF8700 38 | #303030 39 | #505050 40 | #606060 41 | 42 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/LicenseActivity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | * 17 | */ 18 | 19 | package nl.eduvpn.app 20 | 21 | import android.content.Intent 22 | import android.net.Uri 23 | import android.os.Bundle 24 | import android.view.MenuItem 25 | import androidx.core.view.isVisible 26 | import nl.eduvpn.app.base.BaseActivity 27 | import nl.eduvpn.app.databinding.ActivityLicensesBinding 28 | 29 | class LicenseActivity : BaseActivity() { 30 | 31 | override val layout = R.layout.activity_licenses 32 | 33 | override fun onCreate(savedInstanceState: Bundle?) { 34 | super.onCreate(savedInstanceState) 35 | setSupportActionBar(binding.toolbar.toolbar) 36 | supportActionBar?.setDisplayHomeAsUpEnabled(true) 37 | binding.webView.loadUrl("file:///android_asset/licenses.html"); 38 | binding.toolbar.settingsButton.isVisible = false 39 | binding.toolbar.helpButton.setOnClickListener { 40 | startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(BuildConfig.HELP_URI))) 41 | } 42 | } 43 | 44 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 45 | return if (item.itemId == android.R.id.home) { 46 | onBackPressedDispatcher.onBackPressed() 47 | true 48 | } else { 49 | super.onOptionsItemSelected(item) 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_profile_selection.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 8 | 9 | 10 | 17 | 18 | 24 | 25 | 29 | 30 | 31 | 42 | 43 | 44 | 45 | 48 | 49 | -------------------------------------------------------------------------------- /app/src/gov/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 18 | 19 | 20 | #A0A0A0 21 | #A0A0A0 22 | #808080 23 | #a0a0a0 24 | #D0D0D0 25 | #303030 26 | #FFFFFF 27 | #808080 28 | #22B9FF 29 | #f0f0f0 30 | #202020 31 | #C8C8C8 32 | #FFFFFF 33 | #CF0000 34 | #808080 35 | #00000000 36 | #000000 37 | #808080 38 | #A0A0A0 39 | #303030 40 | #505050 41 | #606060 42 | 43 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/utils/serializer/TranslatableStringSerializer.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.utils.serializer 2 | 3 | import kotlinx.serialization.ExperimentalSerializationApi 4 | import kotlinx.serialization.KSerializer 5 | import kotlinx.serialization.SerializationException 6 | import kotlinx.serialization.descriptors.SerialDescriptor 7 | import kotlinx.serialization.encoding.Decoder 8 | import kotlinx.serialization.encoding.Encoder 9 | import kotlinx.serialization.json.JsonElement 10 | import kotlinx.serialization.json.JsonObject 11 | import kotlinx.serialization.json.JsonPrimitive 12 | import nl.eduvpn.app.entity.TranslatableString 13 | 14 | object TranslatableStringSerializer : KSerializer { 15 | 16 | @OptIn(ExperimentalSerializationApi::class) 17 | override val descriptor: SerialDescriptor = 18 | SerialDescriptor("TranslatableString", JsonObject.serializer().descriptor) 19 | 20 | override fun serialize(encoder: Encoder, value: TranslatableString) { 21 | val jsonObject = JsonObject(value.translations.mapValues { (_, v) -> JsonPrimitive(v) }) 22 | encoder.encodeSerializableValue( 23 | JsonObject.serializer(), 24 | jsonObject 25 | ) 26 | } 27 | 28 | override fun deserialize(decoder: Decoder): TranslatableString { 29 | return when (val jsonElement = decoder.decodeSerializableValue(JsonElement.serializer())) { 30 | // Plain string was previously used to store displayName in Instance and in Profile. If 31 | // this is removed from the deserializer, a migration is necessary. 32 | is JsonPrimitive -> if (jsonElement.isString) TranslatableString(jsonElement.content) else null 33 | is JsonObject -> TranslatableString(jsonElement.filterValues { v -> v is JsonPrimitive && v.isString } 34 | .mapValues { m -> 35 | val translation = m.value as JsonPrimitive 36 | translation.content 37 | }) 38 | else -> null 39 | } ?: throw SerializationException("Invalid translatable string") 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/EduVPNApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | */ 17 | 18 | package nl.eduvpn.app; 19 | 20 | import android.content.Context; 21 | import android.os.StrictMode; 22 | 23 | import de.blinkt.openvpn.core.ICSOpenVPNApplication; 24 | import nl.eduvpn.app.inject.EduVPNComponent; 25 | 26 | /** 27 | * Application object which keeps track of the app lifecycle. 28 | * Created by Daniel Zolnai on 2016-09-14. 29 | */ 30 | public class EduVPNApplication extends ICSOpenVPNApplication { 31 | 32 | private EduVPNComponent _component; 33 | 34 | @Override 35 | public void onCreate() { 36 | super.onCreate(); 37 | // Set up the injector 38 | _component = EduVPNComponent.Initializer.init(this); 39 | 40 | // The base class sets a strict VM policy for debug builds, which do not work well with OkHttp 41 | // (see this issue: https://github.com/square/okhttp/issues/3537) 42 | // For now, the best solution seems to be disabling strict mode 43 | StrictMode.VmPolicy policy = new StrictMode.VmPolicy.Builder().build(); 44 | StrictMode.setVmPolicy(policy); 45 | 46 | } 47 | 48 | public EduVPNComponent component() { 49 | return _component; 50 | } 51 | 52 | public static EduVPNApplication get(Context context) { 53 | return (EduVPNApplication)context.getApplicationContext(); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/Instance.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | */ 17 | package nl.eduvpn.app.entity 18 | 19 | import kotlinx.serialization.SerialName 20 | import kotlinx.serialization.Serializable 21 | 22 | /** 23 | * A configuration for an instance. 24 | * Created by Daniel Zolnai on 2016-10-07. 25 | */ 26 | @Serializable 27 | data class Instance( 28 | 29 | @SerialName("base_url") 30 | val baseURI: String, 31 | 32 | @SerialName("display_name") 33 | val displayName: TranslatableString = TranslatableString(), 34 | 35 | @SerialName("keyword_list") 36 | val keywords: TranslatableString? = TranslatableString(), 37 | 38 | @SerialName("logo") 39 | val logoUri: String? = null, 40 | 41 | @SerialName("server_type") 42 | val authorizationType: AuthorizationType = AuthorizationType.Local, 43 | 44 | @SerialName("country_code") 45 | val countryCode: String? = null, 46 | 47 | @SerialName("is_custom") 48 | val isCustom: Boolean = false, 49 | 50 | @SerialName("authentication_url_template") 51 | val authenticationUrlTemplate: String? = null, 52 | 53 | @SerialName("support_contact") 54 | val supportContact: List = emptyList() 55 | ) { 56 | 57 | val sanitizedBaseURI: String 58 | get() = if (baseURI.endsWith("/")) { 59 | baseURI.substring(0, baseURI.length - 1) 60 | } else baseURI 61 | 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/service/OrganizationService.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | */ 17 | package nl.eduvpn.app.service 18 | 19 | import kotlinx.coroutines.Dispatchers 20 | import kotlinx.coroutines.withContext 21 | import nl.eduvpn.app.entity.OrganizationList 22 | import nl.eduvpn.app.entity.ServerList 23 | 24 | /** 25 | * Service which provides the configurations for organization related data model. 26 | * Created by Daniel Zolnai on 2016-10-07. 27 | */ 28 | class OrganizationService( 29 | private val serializerService: SerializerService, 30 | private val backendService: BackendService 31 | ) { 32 | 33 | suspend fun fetchServerList(searchFilter: String) : Result = withContext(Dispatchers.IO) { 34 | try { 35 | val serverListString = backendService.discoverServers(searchFilter) 36 | val result = serializerService.deserializeServerList(serverListString) 37 | return@withContext Result.success(result) 38 | } catch (throwable: Throwable) { 39 | return@withContext Result.failure(throwable) 40 | } 41 | } 42 | 43 | suspend fun fetchOrganizations(searchFilter: String): OrganizationList = withContext(Dispatchers.IO) { 44 | val organizationListString = backendService.discoverOrganizations(searchFilter) 45 | serializerService.deserializeOrganizationList(organizationListString) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/home/res/drawable/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 6 | 10 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/CertExpiredBroadcastReceiver.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app 2 | 3 | import android.app.NotificationManager 4 | import android.app.PendingIntent 5 | import android.content.BroadcastReceiver 6 | import android.content.Context 7 | import android.content.Intent 8 | import androidx.core.app.NotificationCompat 9 | import nl.eduvpn.app.service.VPNService 10 | import nl.eduvpn.app.utils.pendingIntentImmutableFlag 11 | import javax.inject.Inject 12 | 13 | class CertExpiredBroadcastReceiver : BroadcastReceiver() { 14 | 15 | @Inject 16 | protected lateinit var vpnService: VPNService 17 | 18 | override fun onReceive(context: Context, intent: Intent) { 19 | EduVPNApplication.get(context).component().inject(this) 20 | if (intent.action != ACTION) { 21 | return 22 | } 23 | if (vpnService.getStatus() == VPNService.VPNStatus.DISCONNECTED) { 24 | return 25 | } 26 | val channelID = Constants.CERT_EXPIRY_NOTIFICATION_CHANNEL_ID 27 | val notification = NotificationCompat.Builder(context, channelID) 28 | .setSmallIcon(R.drawable.logo_black) 29 | .setContentTitle(context.getString(R.string.cert_expiry_notification_title)) 30 | .setContentText(context.getString(R.string.cert_expiry_notification_text)) 31 | .setContentIntent( 32 | PendingIntent.getActivity( 33 | context, 34 | 0, 35 | Intent(context, MainActivity::class.java), 36 | pendingIntentImmutableFlag 37 | ) 38 | ) 39 | .setAutoCancel(true) 40 | .setPriority(NotificationCompat.PRIORITY_DEFAULT) // Only used on Android <= 7.1 41 | .build() 42 | 43 | val notificationManager = 44 | context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager 45 | 46 | notificationManager.notify(Constants.CERT_EXPIRY_NOTIFICATION_ID, notification) 47 | } 48 | 49 | companion object { 50 | val ACTION = this::class.qualifiedName!!.plus(".cert_expiry") 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_progress_indeterminate_layers.xml: -------------------------------------------------------------------------------- 1 | 2 | 19 | 20 | 25 | 29 | 33 | 37 | 41 | 42 | 46 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /app/src/main/res/menu/logmenu.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 18 | 19 | 25 | 32 | 33 | 35 | 43 | 44 | 45 | 53 | 54 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_help.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 30 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings.xml: -------------------------------------------------------------------------------- 1 | 18 | 19 | 24 | 28 | 32 | 36 | 40 | 44 | 45 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item_message.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 22 | 23 | 36 | 37 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/entity/CurrentServer.kt: -------------------------------------------------------------------------------- 1 | package nl.eduvpn.app.entity 2 | 3 | import kotlinx.serialization.SerialName 4 | import kotlinx.serialization.Serializable 5 | import org.eduvpn.common.ServerType 6 | 7 | @Serializable 8 | data class CurrentServer( 9 | @SerialName("custom_server") 10 | val customServer: CurrentServerInfo? = null, 11 | @SerialName("institute_access_server") 12 | val instituteAccessServer: CurrentServerInfo? = null, 13 | @SerialName("secure_internet_server") 14 | val secureInternetServer: CurrentServerInfo? = null, 15 | @SerialName("server_type") 16 | val serverType: Int? 17 | ) { 18 | 19 | private val info : CurrentServerInfo? = customServer ?: instituteAccessServer ?: secureInternetServer 20 | fun getUniqueId(): String? { 21 | return info?.identifier 22 | } 23 | 24 | fun getDisplayName(): TranslatableString? { 25 | return info?.displayName 26 | } 27 | 28 | fun getProfiles(): List? { 29 | return info?.profiles?.getProfileList() 30 | } 31 | 32 | val currentProfile: Profile? = info?.profiles?.currentProfile 33 | 34 | fun asInstance() : Instance? { 35 | if (info == null) { 36 | return null 37 | } 38 | val authorizationType = when (serverType) { 39 | ServerType.Custom.nativeValue -> AuthorizationType.Organization 40 | ServerType.SecureInternet.nativeValue -> AuthorizationType.Distributed 41 | ServerType.InstituteAccess.nativeValue -> AuthorizationType.Local 42 | else -> return null 43 | } 44 | return Instance( 45 | baseURI = getUniqueId() ?: return null, 46 | displayName = getDisplayName() ?: TranslatableString(), 47 | authorizationType = authorizationType, 48 | supportContact = info.supportContacts 49 | ) 50 | } 51 | } 52 | 53 | @Serializable 54 | data class CurrentServerInfo ( 55 | val identifier: String, 56 | 57 | @SerialName("display_name") 58 | val displayName: TranslatableString, 59 | 60 | val profiles: ProfileWithoutIdMap? = null, 61 | 62 | @SerialName("support_contacts") 63 | val supportContacts: List = emptyList() 64 | ) 65 | 66 | 67 | -------------------------------------------------------------------------------- /app/src/main/java/nl/eduvpn/app/adapter/ProfileAdapter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of eduVPN. 3 | * 4 | * eduVPN is free software: you can redistribute it and/or modify 5 | * it under the terms of the GNU General Public License as published by 6 | * the Free Software Foundation, either version 3 of the License, or 7 | * (at your option) any later version. 8 | * 9 | * eduVPN is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | * GNU General Public License for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License 15 | * along with eduVPN. If not, see . 16 | */ 17 | 18 | package nl.eduvpn.app.adapter 19 | 20 | import android.view.LayoutInflater 21 | import android.view.ViewGroup 22 | import androidx.recyclerview.widget.DiffUtil 23 | import androidx.recyclerview.widget.ListAdapter 24 | import nl.eduvpn.app.adapter.viewholder.ProfileViewHolder 25 | import nl.eduvpn.app.databinding.ListItemProfileBinding 26 | import nl.eduvpn.app.entity.Instance 27 | import nl.eduvpn.app.entity.Profile 28 | 29 | /** 30 | * Adapter for the profile list. 31 | * Created by Daniel Zolnai on 2016-10-11. 32 | */ 33 | class ProfileAdapter(private val instance: Instance) : ListAdapter(object : DiffUtil.ItemCallback() { 34 | override fun areItemsTheSame(oldItem: Profile, newItem: Profile): Boolean { 35 | return oldItem.profileId == newItem.profileId 36 | } 37 | 38 | override fun areContentsTheSame(oldItem: Profile, newItem: Profile): Boolean { 39 | return oldItem == newItem 40 | } 41 | }) { 42 | 43 | 44 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ProfileViewHolder { 45 | return ProfileViewHolder(ListItemProfileBinding.inflate(LayoutInflater.from(parent.context), parent, false)) 46 | } 47 | 48 | public override fun getItem(position: Int): Profile { 49 | return super.getItem(position) 50 | } 51 | 52 | override fun onBindViewHolder(holder: ProfileViewHolder, position: Int) { 53 | val profile = getItem(position) 54 | holder.bind(instance, profile) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_error.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 23 | 24 | 36 | 37 | 43 | 44 |