diff --git a/app/src/main/java/eu/faircode/email/ConnectionHelper.java b/app/src/main/java/eu/faircode/email/ConnectionHelper.java
index 4a59ed6a39..08283c8556 100644
--- a/app/src/main/java/eu/faircode/email/ConnectionHelper.java
+++ b/app/src/main/java/eu/faircode/email/ConnectionHelper.java
@@ -210,6 +210,10 @@ public class ConnectionHelper {
}
private static Boolean isMetered(Context context) {
+ SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
+ boolean standalone_vpn = prefs.getBoolean("standalone_vpn", false);
+ boolean require_validated = prefs.getBoolean("require_validated", false);
+
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (cm == null) {
Log.i("isMetered: no connectivity manager");
@@ -248,10 +252,17 @@ public class ConnectionHelper {
Log.i("isMetered: active caps=" + caps);
- if (caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN) &&
- !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
- Log.i("isMetered: no internet");
- return null;
+ if (caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)) {
+ if (!caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
+ Log.i("isMetered: no internet");
+ return null;
+ }
+ if (require_validated &&
+ Build.VERSION.SDK_INT >= Build.VERSION_CODES.M &&
+ !caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED)) {
+ Log.i("isMetered: not validated");
+ return null;
+ }
}
if (!caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)) {
@@ -265,8 +276,6 @@ public class ConnectionHelper {
return null;
}
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
- boolean standalone_vpn = prefs.getBoolean("standalone_vpn", false);
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 dc2b77a153..69a8fce86d 100644
--- a/app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java
+++ b/app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java
@@ -59,6 +59,7 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre
private Spinner spDownload;
private SwitchCompat swRoaming;
private SwitchCompat swRlah;
+ private SwitchCompat swValidated;
private EditText etTimeout;
private SwitchCompat swPreferIp4;
private SwitchCompat swStandaloneVpn;
@@ -71,7 +72,8 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre
private TextView tvNetworkInfo;
private final static String[] RESET_OPTIONS = new String[]{
- "metered", "download", "roaming", "rlah", "timeout", "prefer_ip4", "standalone_vpn", "tcp_keep_alive", "ssl_harden"
+ "metered", "download", "roaming", "rlah",
+ "require_validated", "timeout", "prefer_ip4", "standalone_vpn", "tcp_keep_alive", "ssl_harden"
};
@Override
@@ -88,6 +90,7 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre
spDownload = view.findViewById(R.id.spDownload);
swRoaming = view.findViewById(R.id.swRoaming);
swRlah = view.findViewById(R.id.swRlah);
+ swValidated = view.findViewById(R.id.swValidated);
etTimeout = view.findViewById(R.id.etTimeout);
swPreferIp4 = view.findViewById(R.id.swPreferIp4);
swStandaloneVpn = view.findViewById(R.id.swStandaloneVpn);
@@ -141,6 +144,14 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre
}
});
+ swValidated.setVisibility(Build.VERSION.SDK_INT < Build.VERSION_CODES.M ? View.GONE : View.VISIBLE);
+ swValidated.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
+ prefs.edit().putBoolean("require_validated", checked).apply();
+ }
+ });
+
etTimeout.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
@@ -307,6 +318,8 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre
swRoaming.setChecked(prefs.getBoolean("roaming", true));
swRlah.setChecked(prefs.getBoolean("rlah", true));
+ swValidated.setChecked(prefs.getBoolean("require_validated", false));
+
int timeout = prefs.getInt("timeout", 0);
etTimeout.setText(timeout == 0 ? null : Integer.toString(timeout));
etTimeout.setHint(Integer.toString(EmailService.DEFAULT_CONNECT_TIMEOUT));
diff --git a/app/src/main/res/layout/fragment_options_connection.xml b/app/src/main/res/layout/fragment_options_connection.xml
index ee7b6e52c6..2e040f7a8e 100644
--- a/app/src/main/res/layout/fragment_options_connection.xml
+++ b/app/src/main/res/layout/fragment_options_connection.xml
@@ -163,6 +163,17 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvRlahHint" />
+
+
+ app:layout_constraintTop_toBottomOf="@id/swValidated" />
Automatically download messages and attachments on a metered connection up to
Download messages and attachments while roaming
Roam like at home
+ Require a validated (checked) connection
Connection timeout (seconds)
Prefer IPv4 over IPv6
Standalone VPN (debug only)