diff --git a/app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java b/app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java index db48309f47..1b0a1f2a0e 100644 --- a/app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java +++ b/app/src/main/java/eu/faircode/email/FragmentOptionsConnection.java @@ -29,6 +29,7 @@ import android.net.NetworkRequest; import android.os.Build; import android.os.Bundle; import android.provider.Settings; +import android.text.TextUtils; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuInflater; @@ -38,6 +39,7 @@ import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.Button; import android.widget.CompoundButton; +import android.widget.EditText; import android.widget.Spinner; import android.widget.TextView; import android.widget.Toast; @@ -54,12 +56,15 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre private Spinner spDownload; private SwitchCompat swRoaming; private SwitchCompat swRlah; + private SwitchCompat swSocks; + private EditText etSocks; + private Button btnSocks; private Button btnManage; private TextView tvConnectionType; private TextView tvConnectionRoaming; private final static String[] RESET_OPTIONS = new String[]{ - "metered", "download", "roaming", "rlah" + "metered", "download", "roaming", "rlah", "socks_enabled", "socks_proxy" }; @Override @@ -76,6 +81,9 @@ 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); + swSocks = view.findViewById(R.id.swSocks); + etSocks = view.findViewById(R.id.etSocks); + btnSocks = view.findViewById(R.id.btnSocks); btnManage = view.findViewById(R.id.btnManage); tvConnectionType = view.findViewById(R.id.tvConnectionType); @@ -124,6 +132,28 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre } }); + swSocks.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton compoundButton, boolean checked) { + prefs.edit().putBoolean("socks_enabled", checked).apply(); + etSocks.setEnabled(checked); + btnSocks.setEnabled(checked); + ServiceSynchronize.reload(getContext(), "socks=" + checked); + } + }); + + btnSocks.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String proxy = etSocks.getText().toString(); + if (TextUtils.isEmpty(proxy)) + prefs.edit().remove("socks_proxy").apply(); + else + prefs.edit().putString("socks_proxy", proxy).apply(); + ServiceSynchronize.reload(getContext(), "socks=" + proxy); + } + }); + final Intent manage = getIntentConnectivity(); btnManage.setVisibility( manage.resolveActivity(getContext().getPackageManager()) == null @@ -221,6 +251,10 @@ public class FragmentOptionsConnection extends FragmentBase implements SharedPre swRoaming.setChecked(prefs.getBoolean("roaming", true)); swRlah.setChecked(prefs.getBoolean("rlah", true)); + swSocks.setChecked(prefs.getBoolean("socks_enabled", false)); + etSocks.setText(prefs.getString("socks_proxy", null)); + etSocks.setEnabled(swSocks.isChecked()); + btnSocks.setEnabled(swSocks.isChecked()); } private static Intent getIntentConnectivity() { diff --git a/app/src/main/java/eu/faircode/email/MailService.java b/app/src/main/java/eu/faircode/email/MailService.java index c914e75c50..5b8e8fd68a 100644 --- a/app/src/main/java/eu/faircode/email/MailService.java +++ b/app/src/main/java/eu/faircode/email/MailService.java @@ -3,8 +3,11 @@ package eu.faircode.email; import android.accounts.Account; import android.accounts.AccountManager; import android.content.Context; +import android.content.SharedPreferences; import android.text.TextUtils; +import androidx.preference.PreferenceManager; + import com.sun.mail.imap.IMAPFolder; import com.sun.mail.imap.IMAPStore; import com.sun.mail.smtp.SMTPTransport; @@ -66,6 +69,24 @@ public class MailService implements AutoCloseable { properties = MessageHelper.getSessionProperties(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + boolean socks_enabled = prefs.getBoolean("socks_enabled", false); + String socks_proxy = prefs.getString("socks_proxy", "localhost:9050"); + + // SOCKS proxy + if (socks_enabled) { + String[] address = socks_proxy.split(":"); + String host = (address.length > 0 ? address[0] : null); + String port = (address.length > 1 ? address[1] : null); + if (TextUtils.isEmpty(host)) + host = "localhost"; + if (TextUtils.isEmpty(port)) + port = "9050"; + properties.put("mail." + protocol + ".socks.host", host); + properties.put("mail." + protocol + ".socks.port", port); + Log.i("Using SOCKS proxy=" + host + ":" + port); + } + properties.put("mail.event.scope", "folder"); properties.put("mail.event.executor", executor); diff --git a/app/src/main/res/layout/fragment_options_connection.xml b/app/src/main/res/layout/fragment_options_connection.xml index 6104ae2c2c..04a24b83f4 100644 --- a/app/src/main/res/layout/fragment_options_connection.xml +++ b/app/src/main/res/layout/fragment_options_connection.xml @@ -119,6 +119,39 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/swRlah" /> + + + + +