diff --git a/app/src/main/java/eu/faircode/email/ConnectionHelper.java b/app/src/main/java/eu/faircode/email/ConnectionHelper.java index 2da5b5df8e..56b49dfcaf 100644 --- a/app/src/main/java/eu/faircode/email/ConnectionHelper.java +++ b/app/src/main/java/eu/faircode/email/ConnectionHelper.java @@ -45,7 +45,7 @@ import java.util.Objects; public class ConnectionHelper { static final List PREF_NETWORK = Collections.unmodifiableList(Arrays.asList( - "metered", "roaming", "rlah" // update network state + "metered", "roaming", "rlah", "require_validated", "vpn_only" // update network state )); // Roam like at home @@ -213,6 +213,7 @@ public class ConnectionHelper { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); boolean standalone_vpn = prefs.getBoolean("standalone_vpn", false); boolean require_validated = prefs.getBoolean("require_validated", false); + boolean vpn_only = prefs.getBoolean("vpn_only", false); ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (cm == null) { @@ -276,6 +277,13 @@ public class ConnectionHelper { return null; } + if (vpn_only) { + boolean vpn = vpnActive(context); + Log.i("VPN only vpn=" + vpn); + if (!vpn) + return null; + } + if (standalone_vpn || caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)) { // NET_CAPABILITY_NOT_METERED is unreliable on older Android versions diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java b/app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java index 3ff8c7a4cc..1ab6c545a9 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java @@ -63,6 +63,7 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre private SwitchCompat swDownloadHeaders; private SwitchCompat swDownloadEml; private SwitchCompat swValidated; + private SwitchCompat swVpnOnly; private EditText etTimeout; private SwitchCompat swPreferIp4; private SwitchCompat swBindSocket; @@ -81,7 +82,8 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre private final static String[] RESET_OPTIONS = new String[]{ "metered", "download", "roaming", "rlah", "download_headers", "download_eml", - "require_validated", "timeout", "prefer_ip4", "bind_socket", "standalone_vpn", "tcp_keep_alive", "ssl_harden" + "require_validated", "vpn_only", + "timeout", "prefer_ip4", "bind_socket", "standalone_vpn", "tcp_keep_alive", "ssl_harden" }; @Override @@ -101,6 +103,7 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre swDownloadHeaders = view.findViewById(R.id.swDownloadHeaders); swDownloadEml = view.findViewById(R.id.swDownloadEml); swValidated = view.findViewById(R.id.swValidated); + swVpnOnly = view.findViewById(R.id.swVpnOnly); etTimeout = view.findViewById(R.id.etTimeout); swPreferIp4 = view.findViewById(R.id.swPreferIp4); swBindSocket = view.findViewById(R.id.swBindSocket); @@ -181,6 +184,13 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre } }); + swVpnOnly.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("vpn_only", checked).apply(); + } + }); + etTimeout.addTextChangedListener(new TextWatcher() { @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { @@ -353,6 +363,7 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre swDownloadEml.setChecked(prefs.getBoolean("download_eml", false)); swValidated.setChecked(prefs.getBoolean("require_validated", false)); + swVpnOnly.setChecked(prefs.getBoolean("vpn_only", false)); int timeout = prefs.getInt("timeout", 0); etTimeout.setText(timeout == 0 ? null : Integer.toString(timeout)); diff --git a/app/src/main/res/layout/fragment_options_connection.xml b/app/src/main/res/layout/fragment_options_connection.xml index 3303bbe295..93f50ea3a4 100644 --- a/app/src/main/res/layout/fragment_options_connection.xml +++ b/app/src/main/res/layout/fragment_options_connection.xml @@ -271,6 +271,17 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/swValidated" /> + + + app:layout_constraintTop_toBottomOf="@id/swVpnOnly" /> + app:constraint_referenced_ids="swValidated,tvValidatedHint,swVpnOnly" /> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index a123a955c9..aa1f5e9861 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -386,6 +386,7 @@ Download all message headers Download raw message files Require a validated (checked) connection + Connect only via a VPN Connection timeout (seconds) Prefer IPv4 over IPv6 Bind sockets to the active network