From 4bb0a589ff81ab40c9c1a5757c703ea279a48353 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 4 Jun 2018 12:09:32 +0200 Subject: [PATCH 01/71] android: Update Gradle plugin and wrapper --- src/frontends/android/app/build.gradle | 8 ++++---- src/frontends/android/build.gradle | 4 +++- .../android/gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/frontends/android/app/build.gradle b/src/frontends/android/app/build.gradle index b708be4cb..15b1d4da3 100644 --- a/src/frontends/android/app/build.gradle +++ b/src/frontends/android/app/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 23 - buildToolsVersion '25.0.0' + buildToolsVersion '27.0.3' defaultConfig { applicationId "org.strongswan.android" @@ -43,7 +43,7 @@ android { } dependencies { - compile 'com.android.support:appcompat-v7:23.3.0' - compile 'com.android.support:design:23.3.0' - testCompile 'junit:junit:4.12' + implementation 'com.android.support:appcompat-v7:23.3.0' + implementation 'com.android.support:design:23.3.0' + testImplementation 'junit:junit:4.12' } diff --git a/src/frontends/android/build.gradle b/src/frontends/android/build.gradle index e52ed0aca..365aa1177 100644 --- a/src/frontends/android/build.gradle +++ b/src/frontends/android/build.gradle @@ -1,14 +1,16 @@ buildscript { repositories { jcenter() + google() } dependencies { - classpath 'com.android.tools.build:gradle:2.3.3' + classpath 'com.android.tools.build:gradle:3.1.3' } } allprojects { repositories { jcenter() + google() } } diff --git a/src/frontends/android/gradle/wrapper/gradle-wrapper.properties b/src/frontends/android/gradle/wrapper/gradle-wrapper.properties index 8c08a361c..8a32ae179 100644 --- a/src/frontends/android/gradle/wrapper/gradle-wrapper.properties +++ b/src/frontends/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Apr 18 15:57:06 CEST 2017 +#Mon Jun 04 11:56:43 CEST 2018 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip From 929badfefd4bd1b958bc22dfe8324ebfd7e43d62 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 4 Jun 2018 15:36:20 +0200 Subject: [PATCH 02/71] android: Build native libraries for all non-deprecated ABIs armeabi has been superseded by armeabi-v7a and the MIPS ABIs were removed with the latest NDK (r17), after being marked deprecated for a while. By not specifying APP_ABI we build for all non-deprecated ABIs. --- src/frontends/android/app/src/main/jni/Application.mk | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/frontends/android/app/src/main/jni/Application.mk b/src/frontends/android/app/src/main/jni/Application.mk index 25b1aa2bd..00a46d70e 100644 --- a/src/frontends/android/app/src/main/jni/Application.mk +++ b/src/frontends/android/app/src/main/jni/Application.mk @@ -1,3 +1 @@ -# select the ABI(s) to build for (see CPU-ARCH-ABIS.html in the NDK docs). -APP_ABI := armeabi arm64-v8a x86 x86_64 mips mips64 APP_PLATFORM := android-19 From 942599b6238a54cd82631e4e19dea86867dd900d Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 5 Jun 2018 15:58:08 +0200 Subject: [PATCH 03/71] atomics: Define HAVE_GCC_ATOMIC_OPERATIONS when building with clang We should probably check for stdatomic.h and use the c11 functions if available. --- src/libstrongswan/utils/utils/atomics.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/libstrongswan/utils/utils/atomics.h b/src/libstrongswan/utils/utils/atomics.h index a973b1adc..4b530ebbf 100644 --- a/src/libstrongswan/utils/utils/atomics.h +++ b/src/libstrongswan/utils/utils/atomics.h @@ -27,8 +27,14 @@ */ typedef u_int refcount_t; +/* use __atomic* built-ins with clang, if available (note that clang also + * defines __GNUC__, however only claims to be GCC 4.2) */ +#if defined(__clang__) +# if __has_builtin(__atomic_add_fetch) +# define HAVE_GCC_ATOMIC_OPERATIONS +# endif /* use __atomic* built-ins with GCC 4.7 and newer */ -#ifdef __GNUC__ +#elif defined(__GNUC__) # if (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)) # define HAVE_GCC_ATOMIC_OPERATIONS # endif From 2afdb92dd0f58a4f28afff21988e3c9c38b34f5b Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Fri, 22 Jun 2018 10:25:25 +0200 Subject: [PATCH 04/71] atomics: Use type of destination in CAS implementation The type of the value was incorrect (void**) if NULL was passed to cas_ptr() as expected value, which caused a compiler warning with Clang because __atomic_compare_exchange_n() expects the types of the first two arguments to be the same. --- src/libstrongswan/utils/utils/atomics.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstrongswan/utils/utils/atomics.h b/src/libstrongswan/utils/utils/atomics.h index 4b530ebbf..c23b361ec 100644 --- a/src/libstrongswan/utils/utils/atomics.h +++ b/src/libstrongswan/utils/utils/atomics.h @@ -53,7 +53,7 @@ typedef u_int refcount_t; #define ref_put(ref) (!__atomic_sub_fetch(ref, 1, __ATOMIC_ACQ_REL)) #define ref_cur(ref) __atomic_load_n(ref, __ATOMIC_RELAXED) -#define _cas_impl(ptr, oldval, newval) ({ typeof(oldval) _old = oldval; \ +#define _cas_impl(ptr, oldval, newval) ({ typeof(*ptr) _old = oldval; \ __atomic_compare_exchange_n(ptr, &_old, newval, FALSE, \ __ATOMIC_SEQ_CST, __ATOMIC_RELAXED); }) #define cas_bool(ptr, oldval, newval) _cas_impl(ptr, oldval, newval) From 08601c58e9159c6d67cb6d1311c6be616631458f Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 4 Jun 2018 15:39:25 +0200 Subject: [PATCH 05/71] android: Suppress self-assign warnings with clang These are triggered by the little endian functions in byteorder.h. --- src/frontends/android/app/src/main/jni/Android.mk | 1 + 1 file changed, 1 insertion(+) diff --git a/src/frontends/android/app/src/main/jni/Android.mk b/src/frontends/android/app/src/main/jni/Android.mk index a46139421..cc6e8e70c 100644 --- a/src/frontends/android/app/src/main/jni/Android.mk +++ b/src/frontends/android/app/src/main/jni/Android.mk @@ -35,6 +35,7 @@ strongswan_CFLAGS := \ -Wno-strict-aliasing \ -Wno-unused-parameter \ -Wno-missing-field-initializers \ + -Wno-self-assign \ -DHAVE___BOOL \ -DHAVE_STDBOOL_H \ -DHAVE_ALLOCA_H \ From 0917caa19519184f0d87f211dd73ef819b2d56e4 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 4 Jun 2018 16:46:25 +0200 Subject: [PATCH 06/71] android: Show an error dialog if we can't get permission for VPNs This is either because a third-party VPN app has the always-on feature enabled, or because the user denied the permission in the system's confirmation dialog. If the always-on feature is enabled for a connection of the built-in VPN client we get an IllegalStateException, for which we show an updated and clearer error message. --- .../src/main/java/org/strongswan/android/ui/MainActivity.java | 4 ++++ src/frontends/android/app/src/main/res/values-de/strings.xml | 3 ++- src/frontends/android/app/src/main/res/values-pl/strings.xml | 3 ++- src/frontends/android/app/src/main/res/values-ru/strings.xml | 3 ++- src/frontends/android/app/src/main/res/values-ua/strings.xml | 3 ++- .../android/app/src/main/res/values-zh-rCN/strings.xml | 3 ++- .../android/app/src/main/res/values-zh-rTW/strings.xml | 3 ++- src/frontends/android/app/src/main/res/values/strings.xml | 3 ++- 8 files changed, 18 insertions(+), 7 deletions(-) diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java index c0e375da4..cd5504ac9 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java @@ -268,6 +268,10 @@ public class MainActivity extends AppCompatActivity implements OnVpnProfileSelec intent.putExtras(mProfileInfo); this.startService(intent); } + else + { /* this happens if the always-on VPN feature is activated by a different app or the user declined */ + VpnNotSupportedError.showWithMessage(this, R.string.vpn_not_supported_no_permission); + } break; default: super.onActivityResult(requestCode, resultCode, data); diff --git a/src/frontends/android/app/src/main/res/values-de/strings.xml b/src/frontends/android/app/src/main/res/values-de/strings.xml index 49a0ab411..ec4c80fe8 100644 --- a/src/frontends/android/app/src/main/res/values-de/strings.xml +++ b/src/frontends/android/app/src/main/res/values-de/strings.xml @@ -24,7 +24,8 @@ Suchen VPN nicht unterstützt Ihr Gerät unterstützt keine VPN Anwendungen.\nBitte kontaktieren Sie den Hersteller. - VPN Verbindungen sind nicht möglich im abgeriegelten Modus. + VPN Verbindungen sind nicht möglich, wenn für ein eingebautes VPN der Always-On-Modus aktiviert ist. + Keine Berechtigung, um VPN Verbindungen zu erstellen. Entweder weil diese vom Benutzer verweigert wurde oder weil für eine andere VPN Anwendung der Always-On-Modus aktiviert ist. Laden… Profil nicht gefunden strongSwan-Verknüpfung diff --git a/src/frontends/android/app/src/main/res/values-pl/strings.xml b/src/frontends/android/app/src/main/res/values-pl/strings.xml index 61fd3f09e..3bf24a419 100644 --- a/src/frontends/android/app/src/main/res/values-pl/strings.xml +++ b/src/frontends/android/app/src/main/res/values-pl/strings.xml @@ -24,7 +24,8 @@ Szukaj Nie obsługiwany VPN Urządzenie nie obsługuje aplikacji VPN.\nProszę skontaktować się z producentem. - Polączenia nie sa możliwe w trybie zamkniętym + VPN connections are not supported if a built-in VPN has the always-on feature enabled. + Unable to get permission to create VPN connections. Either because it was denied by the user, or because a different VPN app has the always-on feature enabled. Wczytywanie… Nie znaleziono profilu Skrót strongSwan diff --git a/src/frontends/android/app/src/main/res/values-ru/strings.xml b/src/frontends/android/app/src/main/res/values-ru/strings.xml index a2b3ada45..f4e596758 100644 --- a/src/frontends/android/app/src/main/res/values-ru/strings.xml +++ b/src/frontends/android/app/src/main/res/values-ru/strings.xml @@ -21,7 +21,8 @@ Поиск VPN не поддерживается Ваше устройство не поддерживат VPN приложение.\nПожалуйста свяжитесь с производителем. - VPN соединения не поддерживаются в режиме lockdown. + VPN connections are not supported if a built-in VPN has the always-on feature enabled. + Unable to get permission to create VPN connections. Either because it was denied by the user, or because a different VPN app has the always-on feature enabled. Загрузка… Профиль не найден Ссылка на strongSwan diff --git a/src/frontends/android/app/src/main/res/values-ua/strings.xml b/src/frontends/android/app/src/main/res/values-ua/strings.xml index bfe4719cd..931c09a6f 100644 --- a/src/frontends/android/app/src/main/res/values-ua/strings.xml +++ b/src/frontends/android/app/src/main/res/values-ua/strings.xml @@ -22,7 +22,8 @@ Пошук VPN не підтримуеться Ваш пристрій не підтримує VPN.\nЗв\'яжіться з виробником. - VPN з\'єднання не пітримується у режимі lockdown. + VPN connections are not supported if a built-in VPN has the always-on feature enabled. + Unable to get permission to create VPN connections. Either because it was denied by the user, or because a different VPN app has the always-on feature enabled. Завантаження… Профіль не знайдено strongSwan посилання diff --git a/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml b/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml index bda732443..7291ccb6c 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml @@ -21,7 +21,8 @@ 搜索 无法支持VPN 您的设备无法支持VPN应用。\n请联系供应商。 - 锁定模式下无法支持VPN连接 + VPN connections are not supported if a built-in VPN has the always-on feature enabled. + Unable to get permission to create VPN connections. Either because it was denied by the user, or because a different VPN app has the always-on feature enabled. 载入中… 未找到配置 strongSwan快捷方式 diff --git a/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml b/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml index 2d4992333..5283d368a 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml @@ -21,7 +21,8 @@ 搜尋 無法支援VPN 您的設備無法使用VPN。\n請聯絡供應商。 - 鎖定模式無法連線VPN + VPN connections are not supported if a built-in VPN has the always-on feature enabled. + Unable to get permission to create VPN connections. Either because it was denied by the user, or because a different VPN app has the always-on feature enabled. 載入中… 沒有找到設定檔 strongSwan快速選單 diff --git a/src/frontends/android/app/src/main/res/values/strings.xml b/src/frontends/android/app/src/main/res/values/strings.xml index dd22d3be7..5c88e43ea 100644 --- a/src/frontends/android/app/src/main/res/values/strings.xml +++ b/src/frontends/android/app/src/main/res/values/strings.xml @@ -24,7 +24,8 @@ Search VPN not supported Your device does not support VPN applications.\nPlease contact the manufacturer. - VPN connections are not supported in lockdown mode. + VPN connections are not supported if a built-in VPN has the always-on feature enabled. + Unable to get permission to create VPN connections. Either because it was denied by the user, or because a different VPN app has the always-on feature enabled. Loading… Profile not found strongSwan shortcut From 93489acc0db76abca248ec44adef9805f612a626 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Tue, 5 Jun 2018 15:42:09 +0200 Subject: [PATCH 07/71] android: UUID is now mandatory Unless there are profiles created with old versions of the app (< 1.8.0) that were never updated since, all profiles should already have a UUID assigned. If not, we do that now with a DB migration. --- .../android/data/VpnProfileDataSource.java | 40 +++++++++++-------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java index 2fef57770..b9161702e 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/data/VpnProfileDataSource.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2017 Tobias Brunner + * Copyright (C) 2012-2018 Tobias Brunner * Copyright (C) 2012 Giuliano Grassi * Copyright (C) 2012 Ralf Sager * HSR Hochschule fuer Technik Rapperswil @@ -63,7 +63,7 @@ public class VpnProfileDataSource private static final String DATABASE_NAME = "strongswan.db"; private static final String TABLE_VPNPROFILE = "vpnprofile"; - private static final int DATABASE_VERSION = 15; + private static final int DATABASE_VERSION = 16; public static final DbColumn[] COLUMNS = new DbColumn[] { new DbColumn(KEY_ID, "INTEGER PRIMARY KEY AUTOINCREMENT", 1), @@ -223,6 +223,26 @@ public class VpnProfileDataSource db.execSQL("ALTER TABLE " + TABLE_VPNPROFILE + " ADD " + KEY_ESP_PROPOSAL + " TEXT;"); } + if (oldVersion < 16) + { /* add a UUID to all entries that haven't one yet */ + db.beginTransaction(); + try + { + Cursor cursor = db.query(TABLE_VPNPROFILE, ALL_COLUMNS, KEY_UUID + " is NULL", null, null, null, null); + for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) + { + ContentValues values = new ContentValues(); + values.put(KEY_UUID, UUID.randomUUID().toString()); + db.update(TABLE_VPNPROFILE, values, KEY_ID + " = " + cursor.getLong(cursor.getColumnIndex(KEY_ID)), null); + } + cursor.close(); + db.setTransactionSuccessful(); + } + finally + { + db.endTransaction(); + } + } } private void updateColumns(SQLiteDatabase db, int version) @@ -385,7 +405,7 @@ public class VpnProfileDataSource { VpnProfile profile = new VpnProfile(); profile.setId(cursor.getLong(cursor.getColumnIndex(KEY_ID))); - profile.setUUID(getUUID(cursor, cursor.getColumnIndex(KEY_UUID))); + profile.setUUID(UUID.fromString(cursor.getString(cursor.getColumnIndex(KEY_UUID)))); profile.setName(cursor.getString(cursor.getColumnIndex(KEY_NAME))); profile.setGateway(cursor.getString(cursor.getColumnIndex(KEY_GATEWAY))); profile.setVpnType(VpnType.fromIdentifier(cursor.getString(cursor.getColumnIndex(KEY_VPN_TYPE)))); @@ -412,7 +432,7 @@ public class VpnProfileDataSource private ContentValues ContentValuesFromVpnProfile(VpnProfile profile) { ContentValues values = new ContentValues(); - values.put(KEY_UUID, profile.getUUID() != null ? profile.getUUID().toString() : null); + values.put(KEY_UUID, profile.getUUID().toString()); values.put(KEY_NAME, profile.getName()); values.put(KEY_GATEWAY, profile.getGateway()); values.put(KEY_VPN_TYPE, profile.getVpnType().getIdentifier()); @@ -441,18 +461,6 @@ public class VpnProfileDataSource return cursor.isNull(columnIndex) ? null : cursor.getInt(columnIndex); } - private UUID getUUID(Cursor cursor, int columnIndex) - { - try - { - return cursor.isNull(columnIndex) ? null : UUID.fromString(cursor.getString(columnIndex)); - } - catch (Exception e) - { - return null; - } - } - private static class DbColumn { public final String Name; From 581f4326d5ed8750113d2726513fbcd0369333b4 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 6 Jun 2018 15:35:00 +0200 Subject: [PATCH 08/71] android: Add additional Intent filter for import Activity with MIME type mask Chrome creates such an Intent when opening downloaded files (not when directly opening them), a MIME type is set, but apparently not ours. --- .../android/app/src/main/AndroidManifest.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/frontends/android/app/src/main/AndroidManifest.xml b/src/frontends/android/app/src/main/AndroidManifest.xml index 287208238..53463fed2 100644 --- a/src/frontends/android/app/src/main/AndroidManifest.xml +++ b/src/frontends/android/app/src/main/AndroidManifest.xml @@ -83,6 +83,7 @@ + @@ -97,6 +98,22 @@ + + + + + + + + + + + + + + + + Date: Wed, 6 Jun 2018 16:29:02 +0200 Subject: [PATCH 09/71] android: Accept a profile's UUID when initiating --- .../strongswan/android/ui/MainActivity.java | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java index cd5504ac9..d91898b36 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java @@ -58,6 +58,7 @@ import org.strongswan.android.ui.VpnProfileListFragment.OnVpnProfileSelectedList import java.io.File; import java.util.ArrayList; import java.util.List; +import java.util.UUID; public class MainActivity extends AppCompatActivity implements OnVpnProfileSelectedListener { @@ -341,14 +342,30 @@ public class MainActivity extends AppCompatActivity implements OnVpnProfileSelec */ private void startVpnProfile(Intent intent, boolean foreground) { - long profileId = intent.getLongExtra(EXTRA_VPN_PROFILE_ID, 0); - if (profileId <= 0) - { /* invalid invocation */ - return; - } + VpnProfile profile = null; + VpnProfileDataSource dataSource = new VpnProfileDataSource(this); dataSource.open(); - VpnProfile profile = dataSource.getVpnProfile(profileId); + String profileUUID = intent.getStringExtra(EXTRA_VPN_PROFILE_ID); + if (profileUUID != null) + { + try + { + profile = dataSource.getVpnProfile(UUID.fromString(profileUUID)); + } + catch (Exception e) + { /* invalid UUID */ + e.printStackTrace(); + } + } + else + { + long profileId = intent.getLongExtra(EXTRA_VPN_PROFILE_ID, 0); + if (profileId > 0) + { + profile = dataSource.getVpnProfile(profileId); + } + } dataSource.close(); if (profile != null) From 71f4a20aa1bcf2edb5ec4ef4086815425f20ee39 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 6 Jun 2018 16:38:26 +0200 Subject: [PATCH 10/71] android: Show profile ID at bottom of advanced settings Can be selected and copied to the clipboard to use in automation software that doesn't support the shortcut. --- .../android/ui/VpnProfileDetailActivity.java | 12 +++++++++++ .../main/res/layout/profile_detail_view.xml | 21 +++++++++++++++++++ .../app/src/main/res/values-de/strings.xml | 3 ++- .../app/src/main/res/values-pl/strings.xml | 1 + .../app/src/main/res/values-ru/strings.xml | 1 + .../app/src/main/res/values-ua/strings.xml | 1 + .../src/main/res/values-zh-rCN/strings.xml | 1 + .../src/main/res/values-zh-rTW/strings.xml | 1 + .../app/src/main/res/values/strings.xml | 3 ++- 9 files changed, 42 insertions(+), 2 deletions(-) diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java index 37c5b3357..a811244e2 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileDetailActivity.java @@ -132,6 +132,8 @@ public class VpnProfileDetailActivity extends AppCompatActivity private EditText mIkeProposal; private TextInputLayoutHelper mEspProposalWrap; private EditText mEspProposal; + private TextView mProfileIdLabel; + private TextView mProfileId; @Override public void onCreate(Bundle savedInstanceState) @@ -194,6 +196,9 @@ public class VpnProfileDetailActivity extends AppCompatActivity /* make the link clickable */ ((TextView)findViewById(R.id.proposal_intro)).setMovementMethod(LinkMovementMethod.getInstance()); + mProfileIdLabel = (TextView)findViewById(R.id.profile_id_label); + mProfileId = (TextView)findViewById(R.id.profile_id); + final SpaceTokenizer spaceTokenizer = new SpaceTokenizer(); mName.setTokenizer(spaceTokenizer); mRemoteId.setTokenizer(spaceTokenizer); @@ -564,6 +569,12 @@ public class VpnProfileDetailActivity extends AppCompatActivity } mShowAdvanced.setVisibility(!show ? View.VISIBLE : View.GONE); mAdvancedSettings.setVisibility(show ? View.VISIBLE : View.GONE); + + if (show && mProfile == null) + { + mProfileIdLabel.setVisibility(View.GONE); + mProfileId.setVisibility(View.GONE); + } } /** @@ -749,6 +760,7 @@ public class VpnProfileDetailActivity extends AppCompatActivity mSelectedApps = mProfile.getSelectedAppsSet(); mIkeProposal.setText(mProfile.getIkeProposal()); mEspProposal.setText(mProfile.getEspProposal()); + mProfileId.setText(mProfile.getUUID().toString()); flags = mProfile.getFlags(); useralias = mProfile.getUserCertificateAlias(); local_id = mProfile.getLocalId(); diff --git a/src/frontends/android/app/src/main/res/layout/profile_detail_view.xml b/src/frontends/android/app/src/main/res/layout/profile_detail_view.xml index d4d88314d..cf7609c44 100644 --- a/src/frontends/android/app/src/main/res/layout/profile_detail_view.xml +++ b/src/frontends/android/app/src/main/res/layout/profile_detail_view.xml @@ -414,6 +414,27 @@ + + + + diff --git a/src/frontends/android/app/src/main/res/values-de/strings.xml b/src/frontends/android/app/src/main/res/values-de/strings.xml index ec4c80fe8..896e53608 100644 --- a/src/frontends/android/app/src/main/res/values-de/strings.xml +++ b/src/frontends/android/app/src/main/res/values-de/strings.xml @@ -1,6 +1,6 @@ Ein Wert wird benötigt, um die Verbindung aufbauen zu können Bitte geben Sie Ihren Benutzernamen ein diff --git a/src/frontends/android/app/src/main/res/values-pl/strings.xml b/src/frontends/android/app/src/main/res/values-pl/strings.xml index 3bf24a419..ce1dc6741 100644 --- a/src/frontends/android/app/src/main/res/values-pl/strings.xml +++ b/src/frontends/android/app/src/main/res/values-pl/strings.xml @@ -113,6 +113,7 @@ This VPN profile already exists, its current settings will be replaced. Import certificate from VPN profile Certificate for \"%1$s\" + Profile ID A value is required to initiate the connection Wprowadź swoją nazwę użytkownika diff --git a/src/frontends/android/app/src/main/res/values-ru/strings.xml b/src/frontends/android/app/src/main/res/values-ru/strings.xml index f4e596758..756473b56 100644 --- a/src/frontends/android/app/src/main/res/values-ru/strings.xml +++ b/src/frontends/android/app/src/main/res/values-ru/strings.xml @@ -110,6 +110,7 @@ This VPN profile already exists, its current settings will be replaced. Import certificate from VPN profile Certificate for \"%1$s\" + Profile ID A value is required to initiate the connection Пожалуйста введите имя пользователя diff --git a/src/frontends/android/app/src/main/res/values-ua/strings.xml b/src/frontends/android/app/src/main/res/values-ua/strings.xml index 931c09a6f..8c165734a 100644 --- a/src/frontends/android/app/src/main/res/values-ua/strings.xml +++ b/src/frontends/android/app/src/main/res/values-ua/strings.xml @@ -111,6 +111,7 @@ This VPN profile already exists, its current settings will be replaced. Import certificate from VPN profile Certificate for \"%1$s\" + Profile ID A value is required to initiate the connection Введіть ім\'я користувача diff --git a/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml b/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml index 7291ccb6c..2d195f638 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml @@ -110,6 +110,7 @@ 此VPN配置已经存在,当前设定将被覆盖。 从VPN配置导入证书 \"%1$s\" 所对应的证书 + Profile ID 必填信息以初始化连接 请输入您的用户名 diff --git a/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml b/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml index 5283d368a..650cd6940 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml @@ -110,6 +110,7 @@ 這個VPN設定檔已經存在,當前設定檔會被覆蓋。 從VPN設定檔匯入憑證 \"%1$s\" 對應的憑證 + Profile ID 請填寫必要訊息才能初始化連線 請輸入您的用戶名稱 diff --git a/src/frontends/android/app/src/main/res/values/strings.xml b/src/frontends/android/app/src/main/res/values/strings.xml index 5c88e43ea..e6cb9dc4c 100644 --- a/src/frontends/android/app/src/main/res/values/strings.xml +++ b/src/frontends/android/app/src/main/res/values/strings.xml @@ -1,6 +1,6 @@ A value is required to initiate the connection Please enter your username From 56dec924ec46f87a9dc5b922e20d1a01108e94fe Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 6 Jun 2018 16:57:31 +0200 Subject: [PATCH 11/71] android: Set compile-/targetSdkVersion to 26 This allows us to add tiles to Quick Settings and enabling the Always-on VPN feature in the VPN settings (both require API level 24, but 26 will be required as targetSdkVersion later this year). --- src/frontends/android/app/build.gradle | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/frontends/android/app/build.gradle b/src/frontends/android/app/build.gradle index 15b1d4da3..418459602 100644 --- a/src/frontends/android/app/build.gradle +++ b/src/frontends/android/app/build.gradle @@ -1,13 +1,13 @@ apply plugin: 'com.android.application' android { - compileSdkVersion 23 + compileSdkVersion 26 buildToolsVersion '27.0.3' defaultConfig { applicationId "org.strongswan.android" minSdkVersion 15 - targetSdkVersion 22 + targetSdkVersion 26 versionCode 50 versionName "1.9.6" } @@ -43,7 +43,8 @@ android { } dependencies { - implementation 'com.android.support:appcompat-v7:23.3.0' - implementation 'com.android.support:design:23.3.0' + implementation 'com.android.support:appcompat-v7:26.0.2' + implementation 'com.android.support:design:26.0.2' + implementation 'com.android.support:support-v4:26.0.2' testImplementation 'junit:junit:4.12' } From 6ca0b46c20d83266a9b93e60ef54a7c91e54008a Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Wed, 6 Jun 2018 18:55:45 +0200 Subject: [PATCH 12/71] android: Add notification channel for API level 26+ Unfortunately, setLockscreenVisibility() doesn't seem to have any effect. So the full notification is shown unless the user manually configures the notification settings. --- .../android/logic/CharonVpnService.java | 27 +++++++++++++++++-- .../app/src/main/res/values-de/strings.xml | 2 ++ .../app/src/main/res/values-pl/strings.xml | 2 ++ .../app/src/main/res/values-ru/strings.xml | 2 ++ .../app/src/main/res/values-ua/strings.xml | 2 ++ .../src/main/res/values-zh-rCN/strings.xml | 2 ++ .../src/main/res/values-zh-rTW/strings.xml | 2 ++ .../app/src/main/res/values/strings.xml | 2 ++ 8 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java index b6e7e2d64..d573d882d 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/logic/CharonVpnService.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012-2017 Tobias Brunner + * Copyright (C) 2012-2018 Tobias Brunner * Copyright (C) 2012 Giuliano Grassi * Copyright (C) 2012 Ralf Sager * HSR Hochschule fuer Technik Rapperswil @@ -19,6 +19,7 @@ package org.strongswan.android.logic; import android.annotation.TargetApi; import android.app.Notification; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; @@ -70,6 +71,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe { private static final String TAG = CharonVpnService.class.getSimpleName(); public static final String DISCONNECT_ACTION = "org.strongswan.android.CharonVpnService.DISCONNECT"; + private static final String NOTIFICATION_CHANNEL = "org.strongswan.android.CharonVpnService.VPN_STATE_NOTIFICATION"; public static final String LOG_FILE = "charon.log"; public static final int VPN_STATE_NOTIFICATION_ID = 1; @@ -162,6 +164,8 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe /* the thread is started when the service is bound */ bindService(new Intent(this, VpnStateService.class), mServiceConnection, Service.BIND_AUTO_CREATE); + + createNotificationChannel(); } @Override @@ -321,6 +325,25 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe stopForeground(true); } + /** + * Create a notification channel for Android 8+ + */ + private void createNotificationChannel() + { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) + { + NotificationChannel channel; + channel = new NotificationChannel(NOTIFICATION_CHANNEL, getString(R.string.permanent_notification_name), + NotificationManager.IMPORTANCE_LOW); + channel.setDescription(getString(R.string.permanent_notification_description)); + channel.setLockscreenVisibility(Notification.VISIBILITY_SECRET); + channel.setShowBadge(false); + NotificationManager notificationManager = getSystemService(NotificationManager.class); + notificationManager.createNotificationChannel(channel); + } + } + + /** * Build a notification matching the current state */ @@ -336,7 +359,7 @@ public class CharonVpnService extends VpnService implements Runnable, VpnStateSe { name = profile.getName(); } - android.support.v4.app.NotificationCompat.Builder builder = new NotificationCompat.Builder(this) + NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL) .setSmallIcon(R.drawable.ic_notification) .setCategory(NotificationCompat.CATEGORY_SERVICE) .setVisibility(publicVersion ? NotificationCompat.VISIBILITY_PUBLIC diff --git a/src/frontends/android/app/src/main/res/values-de/strings.xml b/src/frontends/android/app/src/main/res/values-de/strings.xml index 896e53608..975686e56 100644 --- a/src/frontends/android/app/src/main/res/values-de/strings.xml +++ b/src/frontends/android/app/src/main/res/values-de/strings.xml @@ -29,6 +29,8 @@ Laden… Profil nicht gefunden strongSwan-Verknüpfung + VPN Verbindungsstatus + Zeigt Informationen zum Verbindungsstatus der VPN Verbindung und dient als permanente Notification dazu, den VPN Dienst im Hintergrund am Laufen zu halten. Log diff --git a/src/frontends/android/app/src/main/res/values-pl/strings.xml b/src/frontends/android/app/src/main/res/values-pl/strings.xml index ce1dc6741..835efd531 100644 --- a/src/frontends/android/app/src/main/res/values-pl/strings.xml +++ b/src/frontends/android/app/src/main/res/values-pl/strings.xml @@ -29,6 +29,8 @@ Wczytywanie… Nie znaleziono profilu Skrót strongSwan + VPN connection state + Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background. Log diff --git a/src/frontends/android/app/src/main/res/values-ru/strings.xml b/src/frontends/android/app/src/main/res/values-ru/strings.xml index 756473b56..53e837573 100644 --- a/src/frontends/android/app/src/main/res/values-ru/strings.xml +++ b/src/frontends/android/app/src/main/res/values-ru/strings.xml @@ -26,6 +26,8 @@ Загрузка… Профиль не найден Ссылка на strongSwan + VPN connection state + Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background. Журнал diff --git a/src/frontends/android/app/src/main/res/values-ua/strings.xml b/src/frontends/android/app/src/main/res/values-ua/strings.xml index 8c165734a..8e41daf91 100644 --- a/src/frontends/android/app/src/main/res/values-ua/strings.xml +++ b/src/frontends/android/app/src/main/res/values-ua/strings.xml @@ -27,6 +27,8 @@ Завантаження… Профіль не знайдено strongSwan посилання + VPN connection state + Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background. Журнал diff --git a/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml b/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml index 2d195f638..0cb6bd087 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml @@ -26,6 +26,8 @@ 载入中… 未找到配置 strongSwan快捷方式 + VPN connection state + Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background. 日志 diff --git a/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml b/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml index 650cd6940..168fdd7dd 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml @@ -26,6 +26,8 @@ 載入中… 沒有找到設定檔 strongSwan快速選單 + VPN connection state + Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background. 日誌 diff --git a/src/frontends/android/app/src/main/res/values/strings.xml b/src/frontends/android/app/src/main/res/values/strings.xml index e6cb9dc4c..13d718733 100644 --- a/src/frontends/android/app/src/main/res/values/strings.xml +++ b/src/frontends/android/app/src/main/res/values/strings.xml @@ -29,6 +29,8 @@ Loading… Profile not found strongSwan shortcut + VPN connection state + Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background. Log From ed9d5a314c6a44ce4f7684e896c04cabf9b78ae0 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 7 Jun 2018 14:42:40 +0200 Subject: [PATCH 13/71] android: Replace deprecated ProgressDialog during profile import --- .../android/ui/VpnProfileImportActivity.java | 18 +++++------------- .../main/res/layout/profile_import_view.xml | 7 +++++++ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileImportActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileImportActivity.java index 43c0035cf..d3b7bb471 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileImportActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/VpnProfileImportActivity.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Tobias Brunner + * Copyright (C) 2016-2018 Tobias Brunner * HSR Hochschule fuer Technik Rapperswil * * This program is free software; you can redistribute it and/or modify it @@ -17,11 +17,9 @@ package org.strongswan.android.ui; import android.app.Activity; import android.app.LoaderManager; -import android.app.ProgressDialog; import android.content.AsyncTaskLoader; import android.content.ContentResolver; import android.content.Context; -import android.content.DialogInterface; import android.content.Intent; import android.content.Loader; import android.net.Uri; @@ -96,7 +94,7 @@ public class VpnProfileImportActivity extends AppCompatActivity private TrustedCertificateEntry mUserCertEntry; private String mUserCertLoading; private boolean mHideImport; - private ProgressDialog mProgress; + private android.support.v4.widget.ContentLoadingProgressBar mProgressBar; private TextView mExistsWarning; private ViewGroup mBasicDataGroup; private TextView mName; @@ -167,6 +165,7 @@ public class VpnProfileImportActivity extends AppCompatActivity setContentView(R.layout.profile_import_view); + mProgressBar = findViewById(R.id.progress_bar); mExistsWarning = (TextView)findViewById(R.id.exists_warning); mBasicDataGroup = (ViewGroup)findViewById(R.id.basic_data_group); mName = (TextView)findViewById(R.id.name); @@ -300,14 +299,7 @@ public class VpnProfileImportActivity extends AppCompatActivity private void loadProfile(Uri uri) { - mProgress = ProgressDialog.show(this, null, getString(R.string.loading), - true, true, new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) - { - finish(); - } - }); + mProgressBar.show(); Bundle args = new Bundle(); args.putParcelable(PROFILE_URI, uri); @@ -316,7 +308,7 @@ public class VpnProfileImportActivity extends AppCompatActivity public void handleProfile(ProfileLoadResult data) { - mProgress.dismiss(); + mProgressBar.hide(); mProfile = null; if (data != null && data.ThrownException == null) diff --git a/src/frontends/android/app/src/main/res/layout/profile_import_view.xml b/src/frontends/android/app/src/main/res/layout/profile_import_view.xml index fc06aa5d4..cabfd2944 100644 --- a/src/frontends/android/app/src/main/res/layout/profile_import_view.xml +++ b/src/frontends/android/app/src/main/res/layout/profile_import_view.xml @@ -25,6 +25,13 @@ android:padding="10dp" android:animateLayoutChanges="true" > + + Date: Thu, 7 Jun 2018 14:44:22 +0200 Subject: [PATCH 14/71] android: Remove deprecated progress indicator in MainActivity Support for this was already removed with API level 21. On modern devices loading CA certs should be quick enough anyway. --- .../org/strongswan/android/ui/MainActivity.java | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java index d91898b36..a72936219 100644 --- a/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java +++ b/src/frontends/android/app/src/main/java/org/strongswan/android/ui/MainActivity.java @@ -109,7 +109,6 @@ public class MainActivity extends AppCompatActivity implements OnVpnProfileSelec @Override public void onCreate(Bundle savedInstanceState) { - requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); super.onCreate(savedInstanceState); setContentView(R.layout.main); @@ -432,23 +431,11 @@ public class MainActivity extends AppCompatActivity implements OnVpnProfileSelec */ private class LoadCertificatesTask extends AsyncTask { - @Override - protected void onPreExecute() - { - setProgressBarIndeterminateVisibility(true); - } - @Override protected TrustedCertificateManager doInBackground(Void... params) { return TrustedCertificateManager.getInstance().load(); } - - @Override - protected void onPostExecute(TrustedCertificateManager result) - { - setProgressBarIndeterminateVisibility(false); - } } /** From 4671f023c30bb616f23d9a2ac4412b37e4ecdbe2 Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Thu, 7 Jun 2018 17:12:56 +0200 Subject: [PATCH 15/71] android: Make certificate import activity properly transparent --- .../android/app/src/main/AndroidManifest.xml | 2 +- .../android/app/src/main/res/values/styles.xml | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/frontends/android/app/src/main/AndroidManifest.xml b/src/frontends/android/app/src/main/AndroidManifest.xml index 53463fed2..bfea305cd 100644 --- a/src/frontends/android/app/src/main/AndroidManifest.xml +++ b/src/frontends/android/app/src/main/AndroidManifest.xml @@ -118,7 +118,7 @@ + android:theme="@style/TransparentActivity" > diff --git a/src/frontends/android/app/src/main/res/values/styles.xml b/src/frontends/android/app/src/main/res/values/styles.xml index 82a957813..83f34b6e1 100644 --- a/src/frontends/android/app/src/main/res/values/styles.xml +++ b/src/frontends/android/app/src/main/res/values/styles.xml @@ -1,6 +1,6 @@ + Einstellungen + Voreingestelltes VPN Profil + Verbinden mit zuletzt verwendetem Profil + Log Logdatei senden @@ -76,8 +81,8 @@ Erweiterte Einstellungen Erweiterte Einstellungen anzeigen Server-Identität - Standardwert ist der konfigurierte Server. Eigene Werte werden explizit and den Server gesendet und während der Authentifizierung erzwungen - Standardwert ist \"%1$s\". Eigene Werte werden explizit and den Server gesendet und während der Authentifizierung erzwungen + Standardwert ist der konfigurierte Server. Eigene Werte werden explizit an den Server gesendet und während der Authentifizierung erzwungen + Standardwert ist \"%1$s\". Eigene Werte werden explizit an den Server gesendet und während der Authentifizierung erzwungen MTU des VPN Tunnel-Device Falls der Standardwert in einem bestimmten Netzwerk nicht geeignet ist Server Port @@ -105,7 +110,7 @@ Für non-AEAD/klassische Verschlüsselungsalgorithmen wird ein Integritätsalgorithmus, eine pseudozufällige Funktion (PRF, optional, ansonsten wird eine auf dem Integritätsalgorithmus basierende verwendet) und eine Diffie-Hellman Gruppe benötigt (z.B. aes256-sha256-ecp256). Für kombinierte/AEAD Algorithmen wird der Integritätsalgorithmus weggelassen aber eine PRF wird benötigt (z.B. aes256gcm16-prfsha256-ecp256). IPsec/ESP Algorithmen Für non-AEAD/klassische Verschlüsselungsalgorithmen wird ein Integritätsalgorithmus benötigt, eine Diffie-Hellman Gruppe ist optional (z.B. aes256-sha256 oder aes256-sha256-ecp256). Für kombinierte/AEAD Algorithmen wird der Integritätsalgorithmus weggelassen (z.B. aes256gcm16 oder aes256gcm16-ecp256). Falls eine DH Gruppe angegeben wird, kommt während dem IPsec SA Rekeying ein DH Schlüsselaustausch zur Anwendung. Beim initialen Verbindungsaufbau hat eine DH Gruppe hier keinen Einfluss, weil die Schlüssel dort von der IKE SA abgeleitet werden. Deshalb wird eine Fehlkonfiguration mit dem Server erst später während dem Rekeying zu einem Fehler führen. - VPN Profile importieren + VPN Profil importieren VPN Profil-Import fehlgeschlagen VPN Profil-Import fehlgeschlagen: %1$s Datei nicht gefunden diff --git a/src/frontends/android/app/src/main/res/values-pl/strings.xml b/src/frontends/android/app/src/main/res/values-pl/strings.xml index 835efd531..e9c52f14a 100644 --- a/src/frontends/android/app/src/main/res/values-pl/strings.xml +++ b/src/frontends/android/app/src/main/res/values-pl/strings.xml @@ -32,6 +32,11 @@ VPN connection state Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background. + + Settings + Default VPN profile + Connect to most recently used profile + Log Prześlij log diff --git a/src/frontends/android/app/src/main/res/values-ru/strings.xml b/src/frontends/android/app/src/main/res/values-ru/strings.xml index 53e837573..5f16eecc8 100644 --- a/src/frontends/android/app/src/main/res/values-ru/strings.xml +++ b/src/frontends/android/app/src/main/res/values-ru/strings.xml @@ -29,6 +29,11 @@ VPN connection state Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background. + + Settings + Default VPN profile + Connect to most recently used profile + Журнал Отправить журнал diff --git a/src/frontends/android/app/src/main/res/values-ua/strings.xml b/src/frontends/android/app/src/main/res/values-ua/strings.xml index 8e41daf91..53bcf7164 100644 --- a/src/frontends/android/app/src/main/res/values-ua/strings.xml +++ b/src/frontends/android/app/src/main/res/values-ua/strings.xml @@ -30,6 +30,11 @@ VPN connection state Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background. + + Settings + Default VPN profile + Connect to most recently used profile + Журнал Відправити файл журналу diff --git a/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml b/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml index 0cb6bd087..72098cc47 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rCN/strings.xml @@ -29,6 +29,11 @@ VPN connection state Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background. + + Settings + Default VPN profile + Connect to most recently used profile + 日志 发送日志文件 diff --git a/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml b/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml index 168fdd7dd..ba9fdd044 100644 --- a/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml +++ b/src/frontends/android/app/src/main/res/values-zh-rTW/strings.xml @@ -29,6 +29,11 @@ VPN connection state Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background. + + Settings + Default VPN profile + Connect to most recently used profile + 日誌 發送日誌檔 diff --git a/src/frontends/android/app/src/main/res/values/strings.xml b/src/frontends/android/app/src/main/res/values/strings.xml index 13d718733..cb507beae 100644 --- a/src/frontends/android/app/src/main/res/values/strings.xml +++ b/src/frontends/android/app/src/main/res/values/strings.xml @@ -32,6 +32,11 @@ VPN connection state Provides information about the VPN connection state and serves as permanent notification to keep the VPN service running in the background. + + Settings + Default VPN profile + Connect to most recently used profile + Log Send log file diff --git a/src/frontends/android/app/src/main/res/values/styles.xml b/src/frontends/android/app/src/main/res/values/styles.xml index 83f34b6e1..4b7cc4c5c 100644 --- a/src/frontends/android/app/src/main/res/values/styles.xml +++ b/src/frontends/android/app/src/main/res/values/styles.xml @@ -20,6 +20,7 @@ @color/primary @color/primary_dark @style/AlertDialogTheme + @style/PreferenceThemeOverlay